[Libreoffice-commits] core.git: Branch 'feature/lok_dialog' - 160 commits - avmedia/source basctl/source basic/qa basic/source bean/native bin/find-most-common-warn-messages.py bin/get-bugzilla-attachments-by-mimetype bin/update canvas/source chart2/source comphelper/source compilerplugins/clang compilerplugins/Makefile-clang.mk config_host.mk.in configmgr/source configure.ac connectivity/source cppcanvas/source cpputools/source cui/source dbaccess/source dbaccess/uiconfig desktop/qa desktop/source drawinglayer/source dtrans/source editeng/source embeddedobj/source embedserv/source emfio/source extensions/source extensions/test filter/source forms/source fpicker/source framework/inc framework/source helpcontent2 hwpfilter/source i18npool/inc i18npool/source idlc/source include/basegfx include/comphelper include/connectivity include/editeng include/filter include/LibreOfficeKit include/sal include/sfx2 include/svl include/svx include/tools include/vcl ios/CustomTarget_iOS.mk ios/CustomTarget_Libre OfficeLight_app.mk ios/CustomTarget_Lo_Xcconfig.mk ios/CustomTarget_setup.mk ios/.gitignore ios/LibreOfficeKit ios/LibreOfficeLight ios/Module_ios.mk io/source jvmfwk/plugins jvmfwk/source libreofficekit/Executable_gtktiledviewer.mk libreofficekit/qa libreofficekit/source linguistic/source lotuswordpro/source mysqlc/source oox/source opencl/source package/source postprocess/CustomTarget_images.mk pyuno/source reportdesign/source sal/osl sal/textenc sc/inc sc/qa sc/source sc/uiconfig sdext/source sd/source sd/uiconfig setup_native/source sfx2/source shell/inc shell/qa shell/source slideshow/source solenv/bin solenv/gbuild solenv/gdb solenv/inc starmath/qa starmath/source stoc/source svl/source svtools/source svx/inc svx/source sw/inc sw/qa sw/source sw/uiconfig sysui/CustomTarget_solaris.mk tools/source ucb/source unodevtools/source vbahelper/source vcl/android vcl/headless vcl/inc vcl/Library_vcl.mk vcl/opengl vcl/osx vcl/quartz vcl/source vcl/unx vcl/win vcl/workben winaccessibilit y/source writerfilter/source writerperfect/qa xmlhelp/source xmloff/source xmlsecurity/source

Pranav Kant pranavk at collabora.co.uk
Sun Oct 1 20:17:42 UTC 2017


Rebased ref, commits from common ancestor:
commit 1988140e09098a33e600f0b664a29d2e8444512f
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.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 05c8eff15316..cf030a7f69e8 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -266,19 +266,21 @@ struct _LibreOfficeKitDocumentClass
                        int* pArray,
                        size_t nSize);
 
-    /// WIP
+    /// Paints dialog with given dialog id to the buffer
+    /// @see lok::Document::paintDialog().
     void (*paintDialog) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
 
+    /// @see lok::Document::paintActiveFloatingWindow().
     void (*paintActiveFloatingWindow) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
 
-    /// WIP
+    /// @see lok::Document::postDialogKeyEvent().
     void (*postDialogKeyEvent) (LibreOfficeKitDocument* pThis,
                                 const char* pDialogId,
                                 int nType,
                                 int nCharCode,
                                 int nKeyCode);
 
-    /// WIP
+    /// @see lok::Document::postDialogMouseEvent().
     void (*postDialogMouseEvent) (LibreOfficeKitDocument* pThis,
                                   const char* pDialogId,
                                   int nType,
@@ -288,7 +290,7 @@ struct _LibreOfficeKitDocumentClass
                                   int nButtons,
                                   int nModifier);
 
-        /// WIP
+    /// @see lok::Document::postDialogChildMouseEvent().
     void (*postDialogChildMouseEvent) (LibreOfficeKitDocument* pThis,
                                        const char* pDialogId,
                                        int nType,
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 b046a2e6186e8e063a7c7604c14e354717279775
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 b711c3bc034e..c7f5bfe39e10 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 3df2e6e02927626ff0b69ed398d518327e8ab48a
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 1149f50230b6..b711c3bc034e 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*/
     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 6d5d1e817e9e5bad91297cb48f6dd1b2934ba9c7
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 9fe49aaf350e..8ad25f42a98c 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 7e5962645d9d..48e24b9b6bff 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 22f45e7efd1a923a83c82c8635c4fe118aa4a324
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/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); });
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 8cf1fc5cb89d..a4733c2d2854 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 with 'invalidate' action
-    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 3acd6b78e234..9fe49aaf350e 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 85b1815c57a8..702e88d09cf0 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 c148f09ef873..ec2d09c9d915 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3783,9 +3783,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 c34e9382d16e..7e5962645d9d 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -962,7 +962,7 @@ void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
 {
     if (!comphelper::LibreOfficeKit::isDialogPainting() && mpDialogRenderable && !maID.isEmpty())
     {
-        mpDialogRenderable->notifyDialogInvalidation(maID);
+        mpDialogRenderable->notifyDialog(maID, "invalidate");
     }
 }
 
commit 49443f7ca1876b813644e700a73aa2676aa24b97
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
    
    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/include/vcl/floatwin.hxx b/include/vcl/floatwin.hxx
index fc7df3ada424..f0faa3c3e260 100644
--- a/include/vcl/floatwin.hxx
+++ b/include/vcl/floatwin.hxx
@@ -129,6 +129,7 @@ public:
     SAL_DLLPRIVATE tools::Rectangle&       ImplGetItemEdgeClipRect();
     SAL_DLLPRIVATE bool             ImplIsInPrivatePopupMode() const { return mbInPopupMode; }
     virtual        void             doDeferredInit(WinBits nBits) override;
+    virtual        void    LogicInvalidate(const tools::Rectangle* pRectangle) override;
 
 public:
     explicit        FloatingWindow(vcl::Window* pParent, WinBits nStyle);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index e37f9f274062..1149f50230b6 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -34,11 +34,18 @@ struct GtvLokDialogPrivate
     GtkWidget* pDialogDrawingArea;
     GtkWidget* pFloatingWin;
 
+    // state for dialog
     guint32 m_nLastButtonPressTime;
     guint32 m_nLastButtonReleaseTime;
     guint32 m_nKeyModifier;
     guint32 m_nLastButtonPressed;
 
+    // state for child floating windows
+    guint32 m_nChildLastButtonPressTime;
+    guint32 m_nChildLastButtonReleaseTime;
+    guint32 m_nChildKeyModifier;
+    guint32 m_nChildLastButtonPressed;
+
     gchar* dialogid;
 };
 
@@ -462,6 +469,115 @@ gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
     gtk_widget_queue_draw(priv->pDialogDrawingArea);
 }
 
+static gboolean
+gtv_lok_dialog_floating_win_signal_button(GtkWidget* /*pDialogChildDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
+{
+    GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+    GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+    GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
+    LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+
+    g_info("lok_dialog_floating_win_signal_button: %d, %d (in twips: %d, %d)",
+           (int)pEvent->x, (int)pEvent->y,
+           (int)pixelToTwip(pEvent->x),
+           (int)pixelToTwip(pEvent->y));
+
+    switch (pEvent->type)
+    {
+    case GDK_BUTTON_PRESS:
+    {
+        int nCount = 1;
+        if ((pEvent->time - priv->m_nChildLastButtonPressTime) < 250)
+            nCount++;
+        priv->m_nChildLastButtonPressTime = pEvent->time;
+        int nEventButton = 0;
+        switch (pEvent->button)
+        {
+        case 1:
+            nEventButton = MOUSE_LEFT;
+            break;
+        case 2:
+            nEventButton = MOUSE_MIDDLE;
+            break;
+        case 3:
+            nEventButton = MOUSE_RIGHT;
+            break;
+        }
+        priv->m_nChildLastButtonPressed = nEventButton;
+        pDocument->pClass->postDialogChildMouseEvent(pDocument,
+                                                priv->dialogid,
+                                                LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+                                                (pEvent->x),
+                                                (pEvent->y),
+                                                nCount,
+                                                nEventButton,
+                                                priv->m_nChildKeyModifier);
+
+        break;
+    }
+    case GDK_BUTTON_RELEASE:
+    {
+        int nCount = 1;
+        if ((pEvent->time - priv->m_nChildLastButtonReleaseTime) < 250)
+            nCount++;
+        priv->m_nChildLastButtonReleaseTime = pEvent->time;
+        int nEventButton = 0;
+        switch (pEvent->button)
+        {
+        case 1:
+            nEventButton = MOUSE_LEFT;
+            break;
+        case 2:
+            nEventButton = MOUSE_MIDDLE;
+            break;
+        case 3:
+            nEventButton = MOUSE_RIGHT;
+            break;
+        }
+        priv->m_nChildLastButtonPressed = nEventButton;
+        pDocument->pClass->postDialogChildMouseEvent(pDocument,
+                                                     priv->dialogid,
+                                                     LOK_MOUSEEVENT_MOUSEBUTTONUP,
+                                                     (pEvent->x),
+                                                     (pEvent->y),
+                                                     nCount,
+                                                     nEventButton,
+                                                     priv->m_nChildKeyModifier);
+        break;
+    }
+    default:
+        break;
+    }
+    return FALSE;
+}
+
+static gboolean
+gtv_lok_dialog_floating_win_signal_motion(GtkWidget* /*pDialogDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
+{
+    GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+    GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+    GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
+    LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+
+    g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
+           (int)pEvent->x, (int)pEvent->y,
+           (int)pixelToTwip(pEvent->x),
+           (int)pixelToTwip(pEvent->y));
+
+    pDocument->pClass->postDialogChildMouseEvent(pDocument,
+                                                 priv->dialogid,
+                                                 LOK_MOUSEEVENT_MOUSEMOVE,
+                                                 (pEvent->x),
+                                                 (pEvent->y),
+                                                 1,
+                                                 priv->m_nChildLastButtonPressed,
+                                                 priv->m_nChildKeyModifier);
+
+    return FALSE;
+}
+
 void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
 {
     g_info("Dialog's floating window invalidate");
@@ -477,7 +593,17 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
 
     gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
     gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
+
+    gtk_widget_add_events(pDrawingArea,
+                          GDK_BUTTON_PRESS_MASK
+                          |GDK_POINTER_MOTION_MASK
+                          |GDK_BUTTON_RELEASE_MASK
+                          |GDK_BUTTON_MOTION_MASK);
+
     g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
+    g_signal_connect(G_OBJECT(pDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+    g_signal_connect(G_OBJECT(pDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+    g_signal_connect(G_OBJECT(pDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion), dialog);
 
     gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
     gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
@@ -485,6 +611,7 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
 
     gtk_widget_show_all(priv->pFloatingWin);
     gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+    gtk_widget_grab_focus(pDrawingArea);
 
     // Get the root coords of our new floating window
     GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog));
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 3d269dcadc03..a803a6aa8e16 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -439,6 +439,9 @@ public:
     void postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
                               int nCount, int nButtons, int nModifier) override;
 
+    void postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
+                                   int nCount, int nButtons, int nModifier) override;
+
     void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
 
     void notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos) override;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 9ab338fce7a0..c148f09ef873 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3743,6 +3743,46 @@ void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int n
     }
 }
 
+
+void SwXTextDocument::postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
+                                                int nCount, int nButtons, int nModifier)
+{
+    SolarMutexGuard aGuard;
+
+    // check if dialog is already open
+    SfxViewFrame* pViewFrame = pDocShell->GetView()->GetViewFrame();
+    SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool();
+    const SfxSlot* pSlot = pSlotPool->GetUnoSlot(rDialogID);
+    if (!pSlot)
+    {
+        SAL_WARN("lok.dialog", "No slot found for " << rDialogID);
+        return;
+    }
+    SfxChildWindow* pChild = pViewFrame->GetChildWindow(pSlot->GetSlotId());
+    if (pChild)
+    {
+        Dialog* pDialog = static_cast<Dialog*>(pChild->GetWindow());
+        Point aPos(nX , nY);
+        MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
+
+        switch (nType)
+        {
+        case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
+            pDialog->LogicMouseButtonDownChild(aEvent);
+            break;
+        case LOK_MOUSEEVENT_MOUSEBUTTONUP:
+            pDialog->LogicMouseButtonUpChild(aEvent);
+            break;
+        case LOK_MOUSEEVENT_MOUSEMOVE:
+            pDialog->LogicMouseMoveChild(aEvent);
+            break;
+        default:
+            assert(false);
+            break;
+        }
+    }
+}
+
 void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
 {
     SfxLokHelper::notifyDialogInvalidation(rDialogID);
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 3bd877ea7162..38509814f5b0 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -23,6 +23,7 @@
 #include <vcl/svapp.hxx>
 #include <vcl/event.hxx>
 #include <vcl/ctrl.hxx>
+#include <vcl/floatwin.hxx>
 #include <vcl/decoview.hxx>
 #include <vcl/dialog.hxx>
 #include <vcl/salnativewidgets.hxx>
@@ -420,7 +421,20 @@ void Control::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
     // ignore all of those
     if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isDialogPainting())
     {
-        // For now just invalidate the whole dialog
+        // If parent is a floating window, trigger an invalidate there
+        vcl::Window* pWindow = this;
+        while (pWindow)
+        {
+            if (pWindow->ImplIsFloatingWindow())
+            {
+                dynamic_cast<FloatingWindow*>(pWindow)->LogicInvalidate(nullptr);
+                return;
+            }
+
+            pWindow = pWindow->GetParent();
+        }
+
+        // otherwise, for now, just invalidate the whole dialog
         Dialog* pParentDlg = GetParentDialog();
         if (pParentDlg)
             pParentDlg->LogicInvalidate(nullptr);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 29400ca55982..c34e9382d16e 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -906,6 +906,42 @@ Size Dialog::PaintActiveFloatingWindow(VirtualDevice& rDevice)
     return aRet;
 }
 
+void Dialog::LogicMouseButtonDownChild(const MouseEvent& rMouseEvent)
+{
+    assert(comphelper::LibreOfficeKit::isActive());
+
+    ImplSVData* pSVData = ImplGetSVData();
+    FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+    if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+    {
+        ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonDown, &rMouseEvent);
+    }
+}
+
+void Dialog::LogicMouseButtonUpChild(const MouseEvent& rMouseEvent)
+{
+    assert(comphelper::LibreOfficeKit::isActive());
+
+    ImplSVData* pSVData = ImplGetSVData();
+    FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+    if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+    {
+        ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonUp, &rMouseEvent);
+    }
+}
+
+void Dialog::LogicMouseMoveChild(const MouseEvent& rMouseEvent)
+{
+    assert(comphelper::LibreOfficeKit::isActive());
+
+    ImplSVData* pSVData = ImplGetSVData();
+    FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+    if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+    {
+        ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseMove, &rMouseEvent);
+    }
+}
+
 void Dialog::InvalidateFloatingWindow(const Point& rPos)
 {
     if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
index 16bcb721a612..46b7b330efee 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -585,6 +585,15 @@ bool FloatingWindow::EventNotify( NotifyEvent& rNEvt )
     return bRet;
 }
 
+void FloatingWindow::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+{
+    Dialog* pParentDlg = GetParentDialog();
+    if (pParentDlg)
+    {
+        pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+    }
+}
+
 void FloatingWindow::StateChanged( StateChangedType nType )
 {
     if (nType == StateChangedType::InitShow)
commit 95da1b8720ad72554a1df4e9ae7ececfa41ac82e
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 e120bc92cbf8d5e94e64b151e103900cb8d25a88
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 8896566499c1..3acd6b78e234 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -309,6 +309,19 @@ 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);
+  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);
@@ -316,7 +329,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 690ef24f709c659096a2045bf9b29c3dfa3c4ed3
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 514726ee1e0b..8cf1fc5cb89d 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 with 'invalidate' action
     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 const* 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..8896566499c1 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 d63d0ad2fb4f..85b1815c57a8 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 const* 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 fbb5bf808957..9ab338fce7a0 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3748,6 +3748,32 @@ 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);
+    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..29400ca55982 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -883,10 +883,49 @@ 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)
 {
     if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
     {
+        mpDialogRenderable->notifyDialogChild(maID, "invalidate", rPos);
+    }
+}
+
+void Dialog::CloseFloatingWindow()
+{
+    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..16bcb721a612 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()
@@ -592,6 +593,15 @@ void FloatingWindow::StateChanged( StateChangedType nType )
     }
 
     SystemWindow::StateChanged( nType );
+    Dialog* pParentDlg = GetParentDialog();
+    if (pParentDlg && nType == StateChangedType::InitShow && IsVisible())
+    {
+        pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+    }
+    else if (pParentDlg && !IsVisible())
+    {
+        pParentDlg->CloseFloatingWindow();
+    }
 
     if ( nType == StateChangedType::ControlBackground )
     {
@@ -667,8 +677,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 +724,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 a0a31cfc5c4b2125b53f090c2aa00fc9864b4d02
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 8d2184a3bfa2..fbb5bf808957 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>
@@ -3661,6 +3662,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();
@@ -3740,6 +3743,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 639b36f28d653e1314f8f87a270b2d987320a422
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 782d5f7f952c..8d2184a3bfa2 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3667,9 +3667,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->LOKKeyInput(aEvent);
+            break;
+        case LOK_KEYEVENT_KEYUP:
+            pDialog->LOKKeyUp(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 31da0cd58de898157f22ec6254fb32b80865a5f6
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;
+
+    if (pEvent->state & GDK_CONTROL_MASK)
+        nKeyCode |= KEY_MOD1;
+
+    if (priv->m_nKeyModifier & KEY_MOD2)
+        nKeyCode |= KEY_MOD2;
+
+    if (nKeyCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)) {
+        if (pEvent->keyval >= GDK_KEY_a && pEvent->keyval <= GDK_KEY_z)
+        {
+            nKeyCode |= 512 + (pEvent->keyval - GDK_KEY_a);
+        }
+        else if (pEvent->keyval >= GDK_KEY_A && pEvent->keyval <= GDK_KEY_Z) {
+                nKeyCode |= 512 + (pEvent->keyval - GDK_KEY_A);
+        }
+        else if (pEvent->keyval >= GDK_KEY_0 && pEvent->keyval <= GDK_KEY_9) {
+                nKeyCode |= 256 + (pEvent->keyval - GDK_KEY_0);
+        }
+    }
+
+    std::stringstream ss;
+    ss << "gtv_lok_dialog::postKey(" << pEvent->type << ", " << nCharCode << ", " << nKeyCode << ")";
+    g_info("%s", ss.str().c_str());
+
+    pDocument->pClass->postDialogKeyEvent(pDocument,
+                                          priv->dialogid,
+                                          pEvent->type == GDK_KEY_RELEASE ? LOK_KEYEVENT_KEYUP : LOK_KEYEVENT_KEYINPUT,
+                                          nCharCode,
+                                          nKeyCode);
 
     return FALSE;
 }
@@ -219,12 +333,16 @@ gtv_lok_dialog_init(GtvLokDialog* dialog)
     gtk_widget_add_events(GTK_WIDGET(priv->pDialogDrawingArea),
                           GDK_BUTTON_PRESS_MASK
                           |GDK_BUTTON_RELEASE_MASK
-                          |GDK_BUTTON_MOTION_MASK);
+                          |GDK_BUTTON_MOTION_MASK
+                          |GDK_KEY_PRESS_MASK
+                          |GDK_KEY_RELEASE_MASK);
 
     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);
     g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_signal_button), nullptr);
     g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_signal_motion), nullptr);
+    g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "key-press-event", G_CALLBACK(gtv_lok_dialog_signal_key), nullptr);
+    g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "key-release-event", G_CALLBACK(gtv_lok_dialog_signal_key), nullptr);
     gtk_container_add(GTK_CONTAINER(pContentArea), priv->pDialogDrawingArea);
 }
 
commit b628bd3795371289a610042a36e8c642f15adc06
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Sun Jul 30 05:16:39 2017 +0530

    lokdocview: Remove unnecessary code
    
    Change-Id: I1d744c91f01eb098e9273d2459b63a5444558f39

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 9dd83bf518f5..b5fc11d82d9e 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -815,38 +815,19 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent)
         }
     }
 
-    if (pEvent->type == GDK_KEY_RELEASE)
-    {
-        GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
-        LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY);
-        pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYUP;
-        pLOEvent->m_nCharCode = nCharCode;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list