[Libreoffice-commits] online.git: 4 commits - bundled/include common/Message.hpp kit/ChildSession.cpp kit/ChildSession.hpp kit/Kit.cpp kit/KitHelper.hpp loleaflet/src tools/KitClient.cpp wsd/ClientSession.cpp

Pranav Kant pranavk at collabora.co.uk
Mon Dec 4 21:15:51 UTC 2017


 bundled/include/LibreOfficeKit/LibreOfficeKit.h      |   38 --
 bundled/include/LibreOfficeKit/LibreOfficeKit.hxx    |   77 +----
 bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h |   27 -
 bundled/include/LibreOfficeKit/LibreOfficeKitInit.h  |    1 
 common/Message.hpp                                   |    3 
 kit/ChildSession.cpp                                 |  145 +++++-----
 kit/ChildSession.hpp                                 |    6 
 kit/Kit.cpp                                          |    2 
 kit/KitHelper.hpp                                    |    7 
 loleaflet/src/control/Control.LokDialog.js           |  273 +++++++++----------
 loleaflet/src/core/Socket.js                         |    2 
 loleaflet/src/layer/tile/TileLayer.js                |   42 --
 tools/KitClient.cpp                                  |    3 
 wsd/ClientSession.cpp                                |    9 
 14 files changed, 262 insertions(+), 373 deletions(-)

New commits:
commit a5d4c3bb90df48330c32142e8c235d23be089802
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 5 02:39:26 2017 +0530

    lokdialog: Set view id before posting to LOK dialog api
    
    Change-Id: I53925a71718f1acfc2337f86f97f4f5526546383

diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 4a804aac..326dabcd 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -810,11 +810,9 @@ bool ChildSession::keyEvent(const char* /*buffer*/, int /*length*/,
     }
 
     std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
+    getLOKitDocument()->setView(_viewId);
     if (target == LokEventTargetEnum::Document)
-    {
-        getLOKitDocument()->setView(_viewId);
         getLOKitDocument()->postKeyEvent(type, charcode, keycode);
-    }
     else if (winId != 0)
         getLOKitDocument()->postWindowKeyEvent(winId, type, charcode, keycode);
 
@@ -876,10 +874,10 @@ bool ChildSession::mouseEvent(const char* /*buffer*/, int /*length*/,
 
     std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
 
+    getLOKitDocument()->setView(_viewId);
     switch (target)
     {
     case LokEventTargetEnum::Document:
-        getLOKitDocument()->setView(_viewId);
         getLOKitDocument()->postMouseEvent(type, x, y, count, buttons, modifier);
         break;
     case LokEventTargetEnum::Window:
@@ -1026,6 +1024,8 @@ bool ChildSession::sendWindowCommand(const char* /*buffer*/, int /*length*/, con
         reader >> winId;
     }
 
+    getLOKitDocument()->setView(_viewId);
+
     if (tokens.size() > 2 && tokens[2] == "close")
         getLOKitDocument()->postWindow(winId, LOK_WINDOW_CLOSE);
 
commit 53fc694a3c413684179c4cf1026b2c6d3e8959ef
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 5 00:41:02 2017 +0530

    lokdialog: Use dialog close LOK API when user clicks 'X'
    
    Change-Id: I3a90eb8b83688eed7db8228763633e31f82e58d1

diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index 7de22985..4a804aac 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -13,6 +13,9 @@
 
 #include <sstream>
 
+#define LOK_USE_UNSTABLE_API
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+
 #include <Poco/JSON/Object.h>
 #include <Poco/JSON/Parser.h>
 #include <Poco/Net/WebSocket.h>
@@ -233,7 +236,8 @@ bool ChildSession::_handleInput(const char *buffer, int length)
                tokens[0] == "resetselection" ||
                tokens[0] == "saveas" ||
                tokens[0] == "useractive" ||
-               tokens[0] == "userinactive");
+               tokens[0] == "userinactive" ||
+               tokens[0] == "windowcommand");
 
         if (tokens[0] == "clientzoom")
         {
@@ -311,6 +315,10 @@ bool ChildSession::_handleInput(const char *buffer, int length)
         {
             setIsActive(false);
         }
+        else if (tokens[0] == "windowcommand")
+        {
+            sendWindowCommand(buffer, length, tokens);
+        }
         else
         {
             assert(false && "Unknown command token.");
@@ -1005,6 +1013,25 @@ bool ChildSession::renderWindow(const char* /*buffer*/, int /*length*/, const st
     return true;
 }
 
+
+bool ChildSession::sendWindowCommand(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+{
+    std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
+    getLOKitDocument()->setView(_viewId);
+
+    unsigned winId = 0;
+    if (tokens.size() > 1)
+    {
+        std::istringstream reader(tokens[1]);
+        reader >> winId;
+    }
+
+    if (tokens.size() > 2 && tokens[2] == "close")
+        getLOKitDocument()->postWindow(winId, LOK_WINDOW_CLOSE);
+
+    return true;
+}
+
 bool ChildSession::selectGraphic(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
 {
     int type, x, y;
diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp
index 47c79421..c0ca190d 100644
--- a/kit/ChildSession.hpp
+++ b/kit/ChildSession.hpp
@@ -198,6 +198,7 @@ private:
     bool saveAs(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool setClientPart(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool setPage(const char* buffer, int length, const std::vector<std::string>& tokens);
+    bool sendWindowCommand(const char* buffer, int length, const std::vector<std::string>& tokens);
 
     void rememberEventsForInactiveUser(const int type, const std::string& payload);
 
diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js
index 18e4cd24..c8a8b0f8 100644
--- a/loleaflet/src/control/Control.LokDialog.js
+++ b/loleaflet/src/control/Control.LokDialog.js
@@ -61,13 +61,17 @@ L.Control.LokDialog = L.Control.extend({
 		return [x, y, width, height].join(',');
 	},
 
-	_sendWindowCommand: function(id, rectangle) {
+	_sendPaintWindow: function(id, rectangle) {
 		if (rectangle)
 			rectangle = rectangle.replace(/ /g, '');
 
 		this._map._socket.sendMessage('paintwindow ' + id + (rectangle ? ' rectangle=' + rectangle : ''));
 	},
 
+	_sendCloseWindow: function(id) {
+		this._map._socket.sendMessage('windowcommand ' + id + ' close');
+	},
+
 	_isRectangleValid: function(rect) {
 		rect = rect.split(',');
 		if (parseInt(rect[0]) < 0 || parseInt(rect[1]) < 0 || parseInt(rect[2]) < 0 || parseInt(rect[3]) < 0)
@@ -84,7 +88,7 @@ L.Control.LokDialog = L.Control.extend({
 				this._width = width;
 				this._height = height;
 				this._launchDialog(this._toDlgPrefix(e.id));
-				this._sendWindowCommand(e.id, this._createRectStr());
+				this._sendPaintWindow(e.id, this._createRectStr());
 			} else if (e.winType === 'child') {
 				if (!this._isOpen(e.parentId))
 					return;
@@ -100,7 +104,7 @@ L.Control.LokDialog = L.Control.extend({
 				this._dialogs[parentId].childx = left;
 				this._dialogs[parentId].childy = top;
 				this._createDialogChild(e.id, parentId, top, left);
-				this._sendWindowCommand(e.id, this._createRectStr(0, 0, width, height));
+				this._sendPaintWindow(e.id, this._createRectStr(0, 0, width, height));
 			}
 		} else if (e.action === 'invalidate') {
 			var parent = this._getParentDialog(e.id);
@@ -114,7 +118,7 @@ L.Control.LokDialog = L.Control.extend({
 				if (!rectangle)
 					rectangle = '0,0,' + this._width + ',' + this._height;
 			}
-			this._sendWindowCommand(e.id, rectangle);
+			this._sendPaintWindow(e.id, rectangle);
 		} else if (e.action === 'size_changed') {
 			this._width = parseInt(e.size.split(',')[0]);
 			this._height = parseInt(e.size.split(',')[1]);
@@ -125,7 +129,7 @@ L.Control.LokDialog = L.Control.extend({
 			$('#' + strDlgId).remove();
 			this._launchDialog(strDlgId);
 			$('#' + strDlgId).dialog('option', 'title', this._title);
-			this._sendWindowCommand(e.id, this._createRectStr());
+			this._sendPaintWindow(e.id, this._createRectStr());
 		} else if (e.action === 'cursor_invalidate') {
 			if (this._isOpen(e.id) && !!e.rectangle) {
 				var rectangle = e.rectangle.split(',');
@@ -151,7 +155,7 @@ L.Control.LokDialog = L.Control.extend({
 			if (parent)
 				this._onDialogChildClose(this._toDlgPrefix(parent));
 			else
-				this._onDialogClose(e.id);
+				this._onDialogClose(e.id, false);
 		}
 	},
 
@@ -181,7 +185,7 @@ L.Control.LokDialog = L.Control.extend({
 			resizable: false,
 			dialogClass: 'lokdialog_container',
 			close: function() {
-				that._onDialogClose(strDlgId);
+				that._onDialogClose(that._toRawDlgId(strDlgId), true);
 			}
 		});
 
@@ -263,7 +267,9 @@ L.Control.LokDialog = L.Control.extend({
 		}
 	},
 
-	_onDialogClose: function(dialogId) {
+	_onDialogClose: function(dialogId, notifyBackend) {
+		if (notifyBackend)
+			this._sendCloseWindow(dialogId);
 		$('#' + this._toDlgPrefix(dialogId)).remove();
 		this._map.focus();
 		delete this._dialogs[dialogId];
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index b607ed0f..2bba11cf 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -156,7 +156,8 @@ bool ClientSession::_handleInput(const char *buffer, int length)
              tokens[0] != "uno" &&
              tokens[0] != "useractive" &&
              tokens[0] != "userinactive" &&
-             tokens[0] != "paintwindow")
+             tokens[0] != "paintwindow" &&
+             tokens[0] != "windowcommand")
     {
         sendTextFrame("error: cmd=" + tokens[0] + " kind=unknown");
         return false;
commit fc432c85ea20c6d9857472de2db61b1279ce610f
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Mon Dec 4 22:16:07 2017 +0530

    Update bundled headers
    
    Change-Id: I15c60a5b9f6c61d5ab276fc08058f89bca272f4e

diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKit.h b/bundled/include/LibreOfficeKit/LibreOfficeKit.h
index 02e8e50e..f9c9e22a 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKit.h
@@ -224,6 +224,7 @@ struct _LibreOfficeKitDocumentClass
             int nTilePixelHeight,
             int nTileTwipWidth,
             int nTileTwipHeight);
+
     /// @see lok::Document::setVisibleArea).
     void (*setClientVisibleArea) (LibreOfficeKitDocument* pThis, int nX, int nY, int nWidth, int nHeight);
 
@@ -269,31 +270,26 @@ struct _LibreOfficeKitDocumentClass
                        int* pArray,
                        size_t nSize);
 
-    /// Paints dialog with given dialog id to the buffer
-    /// @see lok::Document::paintDialog().
-    void (*paintDialog) (LibreOfficeKitDocument* pThis, const char* pDialogId,
+    /// Paints window with given id to the buffer
+    /// @see lok::Document::paintWindow().
+    void (*paintWindow) (LibreOfficeKitDocument* pThis, unsigned nWindowId,
                          unsigned char* pBuffer,
                          const int x, const int y,
                          const int width, const int height);
 
-    /// Get info about dialog with given dialog id
-    /// @see lok::Document::getDialogInfo().
-    void (*getDialogInfo) (LibreOfficeKitDocument* pThis, const char* pDialogId,
-                           char** pDialogTitle, int* pWidth, int* pHeight);
-
-    /// @see lok::Document::paintActiveFloatingWindow().
-    void (*paintActiveFloatingWindow) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+    /// @see lok::Document::postWindow().
+    void (*postWindow) (LibreOfficeKitDocument* pThis, unsigned nWindowId, int nAction);
 
-    /// @see lok::Document::postDialogKeyEvent().
-    void (*postDialogKeyEvent) (LibreOfficeKitDocument* pThis,
-                                const char* pDialogId,
+    /// @see lok::Document::postWindowKeyEvent().
+    void (*postWindowKeyEvent) (LibreOfficeKitDocument* pThis,
+                                unsigned nWindowId,
                                 int nType,
                                 int nCharCode,
                                 int nKeyCode);
 
-    /// @see lok::Document::postDialogMouseEvent().
-    void (*postDialogMouseEvent) (LibreOfficeKitDocument* pThis,
-                                  const char* pDialogId,
+    /// @see lok::Document::postWindowMouseEvent().
+    void (*postWindowMouseEvent) (LibreOfficeKitDocument* pThis,
+                                  unsigned nWindowId,
                                   int nType,
                                   int nX,
                                   int nY,
@@ -301,16 +297,6 @@ struct _LibreOfficeKitDocumentClass
                                   int nButtons,
                                   int nModifier);
 
-    /// @see lok::Document::postDialogChildMouseEvent().
-    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/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx b/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
index 1c4fcd03..835710e0 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -156,62 +156,34 @@ public:
     }
 
     /**
-     * Renders a dialog with give dialog id and writes the width and height of the rendered dialog
+     * Renders a window (dialog, popup, etc.) with give id
      *
-     * Client must truncate pBuffer according to the nWidth and nHeight returned after the call.
-     *
-     * @param pDialogId Unique dialog id to be painted
+     * @param nWindowId
      * @param pBuffer Buffer with enough memory allocated to render any dialog
      * @param x x-coordinate from where the dialog should start painting
      * @param y y-coordinate from where the dialog should start painting
      * @param width The width of the dialog image to be painted
      * @param height The height of the dialog image to be painted
      */
-    void paintDialog(const char* pDialogId,
+    void paintWindow(unsigned nWindowId,
                      unsigned char* pBuffer,
                      const int x,
                      const int y,
                      const int width,
                      const int height)
     {
-        return mpDoc->pClass->paintDialog(mpDoc, pDialogId, pBuffer,
+        return mpDoc->pClass->paintWindow(mpDoc, nWindowId, pBuffer,
                                           x, y, width, height);
     }
 
-    /* Get info about dialog with given dialog id
-     *
-     * @param pDialogId Unique dialog id for which to get info about
-     * @param pDialogTitle Pointer to pointer pointing to string containing the
-     * dialog title. Caller should the pointer to allocated string themselves.
-     * @param pWidth The width of the dialog
-     * @param pHeight The height of the dialog
-     */
-    void getDialogInfo(const char* pDialogId,
-                       char** pDialogTitle,
-                       int& pWidth,
-                       int& pHeight)
-    {
-        return mpDoc->pClass->getDialogInfo(mpDoc, pDialogId, pDialogTitle, &pWidth, &pHeight);
-
-    }
-
     /**
-     * Renders the active floating window of a dialog
-     *
-     * Client must truncate pBuffer according to the nWidth and nHeight returned after the call.
+     * Posts a command to the window (dialog, popup, etc.) with given id
      *
-     * @param pDialogId Unique dialog id
-     * @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
+     * @param nWindowid
      */
-    void paintActiveFloatingWindow(const char* pDialogId,
-                                   unsigned char* pBuffer,
-                                   int& nWidth,
-                                   int& nHeight)
+    void postWindow(unsigned nWindowId, int nAction)
     {
-        return mpDoc->pClass->paintActiveFloatingWindow(mpDoc, pDialogId, pBuffer,
-                                                        &nWidth, &nHeight);
+        return mpDoc->pClass->postWindow(mpDoc, nWindowId, nAction);
     }
 
     /**
@@ -282,14 +254,14 @@ public:
     /**
      * Posts a keyboard event to the dialog
      *
-     * @param pDialogId Dialog id on which key event should be posted
+     * @param nWindowId
      * @param nType Event type, like press or release.
      * @param nCharCode contains the Unicode character generated by this event or 0
      * @param nKeyCode contains the integer code representing the key of the event (non-zero for control keys)
      */
-    void postDialogKeyEvent(const char* pDialogId, int nType, int nCharCode, int nKeyCode)
+    void postWindowKeyEvent(unsigned nWindowId, int nType, int nCharCode, int nKeyCode)
     {
-        mpDoc->pClass->postDialogKeyEvent(mpDoc, pDialogId, nType, nCharCode, nKeyCode);
+        mpDoc->pClass->postWindowKeyEvent(mpDoc, nWindowId, nType, nCharCode, nKeyCode);
     }
 
     /**
@@ -308,25 +280,9 @@ public:
     }
 
     /**
-     * Posts a mouse event to the dialog with given id.
-     *
-     * @param pDialogId 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 a mouse event to the child of a dialog with given id.
+     * Posts a mouse event to the window with given id.
      *
-     * @param aDialogId Dialog id
+     * @param nWindowId
      * @param nType Event type, like down, move or up.
      * @param nX horizontal position in document coordinates
      * @param nY vertical position in document coordinates
@@ -334,12 +290,11 @@ public:
      * @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 postDialogChildMouseEvent(const char* pDialogId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
+    void postWindowMouseEvent(unsigned nWindowId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
     {
-        mpDoc->pClass->postDialogChildMouseEvent(mpDoc, pDialogId, nType, nX, nY, nCount, nButtons, nModifier);
+        mpDoc->pClass->postWindowMouseEvent(mpDoc, nWindowId, nType, nX, nY, nCount, nButtons, nModifier);
     }
 
-
     /**
      * Posts an UNO command to the document.
      *
@@ -465,7 +420,7 @@ public:
     }
 
     /**
-     * Show/Hide a single row/column header outline for Calc dosuments.
+     * Show/Hide a single row/column header outline for Calc documents.
      *
      * @param bColumn - if we are dealing with a column or row group
      * @param nLevel - the level to which the group belongs
diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 62b9faf7..cf85d7c6 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -40,6 +40,12 @@ typedef enum
 }
 LibreOfficeKitTileMode;
 
+typedef enum
+{
+    LOK_WINDOW_CLOSE
+}
+LibreOfficeKitWindowAction;
+
 /** Optional features of LibreOfficeKit, in particular callbacks that block
  *  LibreOfficeKit until the corresponding reply is received, which would
  *  deadlock if the client does not support the feature.
@@ -525,26 +531,7 @@ typedef enum
     /**
      * Dialog invalidation
      */
-    LOK_CALLBACK_DIALOG = 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
+    LOK_CALLBACK_WINDOW = 36,
 }
 LibreOfficeKitCallbackType;
 
diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKitInit.h b/bundled/include/LibreOfficeKit/LibreOfficeKitInit.h
index f95ee496..a0c111a9 100644
--- a/bundled/include/LibreOfficeKit/LibreOfficeKitInit.h
+++ b/bundled/include/LibreOfficeKit/LibreOfficeKitInit.h
@@ -234,6 +234,7 @@ static void *lok_dlopen( const char *install_path, char ** _imp_lib )
         }
     }
 #else
+    (void)install_path;
     imp_lib = strdup("the app executable");
     dlhandle = RTLD_MAIN_ONLY;
 #endif
commit 849eb0d500f549c6feb4eae7d5bba1710945678b
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Mon Dec 4 22:13:50 2017 +0530

    lokdialog: Adapt to LOK dialog API changes
    
    Change-Id: I653304e71573eb253e09a72bc87d54b8554ba7ff

diff --git a/common/Message.hpp b/common/Message.hpp
index bfd38cb7..cfca3f81 100644
--- a/common/Message.hpp
+++ b/common/Message.hpp
@@ -131,8 +131,7 @@ private:
         if (_tokens[0] == "tile:" ||
             _tokens[0] == "tilecombine:" ||
             _tokens[0] == "renderfont:" ||
-            _tokens[0] == "dialogpaint:" ||
-            _tokens[0] == "dialogchildpaint:")
+            _tokens[0] == "windowpaint:")
         {
             return Type::Binary;
         }
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index ca4c855e..7de22985 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -202,9 +202,9 @@ bool ChildSession::_handleInput(const char *buffer, int length)
     {
         return getStatus(buffer, length);
     }
-    else if (tokens[0] == "dialog" || tokens[0] == "dialogchild")
+    else if (tokens[0] == "paintwindow")
     {
-        return renderDialog(buffer, length, tokens);
+        return renderWindow(buffer, length, tokens);
     }
     else if (tokens[0] == "tile" || tokens[0] == "tilecombine")
     {
@@ -224,10 +224,9 @@ bool ChildSession::_handleInput(const char *buffer, int length)
                tokens[0] == "paste" ||
                tokens[0] == "insertfile" ||
                tokens[0] == "key" ||
-               tokens[0] == "dialogkey" ||
+               tokens[0] == "windowkey" ||
                tokens[0] == "mouse" ||
-               tokens[0] == "dialogmouse" ||
-               tokens[0] == "dialogchildmouse" ||
+               tokens[0] == "windowmouse" ||
                tokens[0] == "uno" ||
                tokens[0] == "selecttext" ||
                tokens[0] == "selectgraphic" ||
@@ -272,21 +271,17 @@ bool ChildSession::_handleInput(const char *buffer, int length)
         {
             return keyEvent(buffer, length, tokens, LokEventTargetEnum::Document);
         }
-        else if (tokens[0] == "dialogkey")
+        else if (tokens[0] == "windowkey")
         {
-            return keyEvent(buffer, length, tokens, LokEventTargetEnum::Dialog);
+            return keyEvent(buffer, length, tokens, LokEventTargetEnum::Window);
         }
         else if (tokens[0] == "mouse")
         {
             return mouseEvent(buffer, length, tokens, LokEventTargetEnum::Document);
         }
-        else if (tokens[0] == "dialogmouse")
+        else if (tokens[0] == "windowmouse")
         {
-            return mouseEvent(buffer, length, tokens, LokEventTargetEnum::Dialog);
-        }
-        else if (tokens[0] == "dialogchildmouse")
-        {
-            return mouseEvent(buffer, length, tokens, LokEventTargetEnum::DialogChild);
+            return mouseEvent(buffer, length, tokens, LokEventTargetEnum::Window);
         }
         else if (tokens[0] == "uno")
         {
@@ -763,19 +758,19 @@ bool ChildSession::keyEvent(const char* /*buffer*/, int /*length*/,
                             const LokEventTargetEnum target)
 {
     int type, charcode, keycode;
-    unsigned dialogId = 0;
+    unsigned winId = 0;
     unsigned counter = 1;
     unsigned expectedTokens = 4; // cmdname(key), type, char, key are strictly required
-    if (target == LokEventTargetEnum::Dialog || target == LokEventTargetEnum::DialogChild)
+    if (target == LokEventTargetEnum::Window)
     {
         if (tokens.size() <= counter ||
-            !getTokenUInt32(tokens[counter++], "dialogid", dialogId))
+            !getTokenUInt32(tokens[counter++], "id", winId))
         {
-            LOG_ERR("Dialog key event expects a valid dialogid= attribute");
+            LOG_ERR("Window key event expects a valid id= attribute");
             sendTextFrame("error: cmd=" + std::string(tokens[0]) + " kind=syntax");
             return false;
         }
-        else // dialogid= attribute is found
+        else // id= attribute is found
             expectedTokens++;
     }
 
@@ -812,8 +807,8 @@ bool ChildSession::keyEvent(const char* /*buffer*/, int /*length*/,
         getLOKitDocument()->setView(_viewId);
         getLOKitDocument()->postKeyEvent(type, charcode, keycode);
     }
-    else if (dialogId != 0)
-        getLOKitDocument()->postDialogKeyEvent(dialogId, type, charcode, keycode);
+    else if (winId != 0)
+        getLOKitDocument()->postWindowKeyEvent(winId, type, charcode, keycode);
 
     return true;
 }
@@ -829,18 +824,18 @@ bool ChildSession::mouseEvent(const char* /*buffer*/, int /*length*/,
     int buttons = 1; // left button
     int modifier = 0;
 
-    unsigned dialogId = 0;
+    unsigned winId = 0;
     unsigned counter = 1;
     unsigned minTokens = 5; // cmdname(mouse), type, x, y, count are strictly required
-    if (target == LokEventTargetEnum::Dialog || target == LokEventTargetEnum::DialogChild)
+    if (target == LokEventTargetEnum::Window)
     {
         if (tokens.size() <= counter ||
-            !getTokenUInt32(tokens[counter++], "dialogid", dialogId))
+            !getTokenUInt32(tokens[counter++], "id", winId))
         {
-            LOG_ERR("Dialog mouse event expects a valid dialogid= attribute");
+            LOG_ERR("Window mouse event expects a valid id= attribute");
             success = false;
         }
-        else // dialogid= attribute is found
+        else // id= attribute is found
             minTokens++;
     }
 
@@ -879,11 +874,8 @@ bool ChildSession::mouseEvent(const char* /*buffer*/, int /*length*/,
         getLOKitDocument()->setView(_viewId);
         getLOKitDocument()->postMouseEvent(type, x, y, count, buttons, modifier);
         break;
-    case LokEventTargetEnum::Dialog:
-        getLOKitDocument()->postDialogMouseEvent(dialogId, type, x, y, count, buttons, modifier);
-        break;
-    case LokEventTargetEnum::DialogChild:
-        getLOKitDocument()->postDialogChildMouseEvent(dialogId, type, x, y, count, buttons, modifier);
+    case LokEventTargetEnum::Window:
+        getLOKitDocument()->postWindowMouseEvent(winId, type, x, y, count, buttons, modifier);
         break;
     default:
         assert(false && "Unsupported mouse target type");
@@ -950,17 +942,16 @@ bool ChildSession::selectText(const char* /*buffer*/, int /*length*/, const std:
     return true;
 }
 
-bool ChildSession::renderDialog(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
+bool ChildSession::renderWindow(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens)
 {
     std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
     getLOKitDocument()->setView(_viewId);
-    const bool isChild = (tokens[0] == "dialogchild");
 
-    unsigned dialogId = 0;
+    unsigned winId = 0;
     if (tokens.size() > 1)
     {
         std::istringstream reader(tokens[1]);
-        reader >> dialogId;
+        reader >> winId;
     }
 
     int startX = 0, startY = 0;
@@ -975,43 +966,27 @@ bool ChildSession::renderDialog(const char* /*buffer*/, int /*length*/, const st
         bufferHeight = std::atoi(rectParts[3].c_str());
     }
     else
-        LOG_WRN("dialog command doesn't specify a rectangle= attribute.");
+        LOG_WRN("windowpaint command doesn't specify a rectangle= attribute.");
 
     size_t pixmapDataSize = 4 * bufferWidth * bufferHeight;
     std::vector<unsigned char> pixmap(pixmapDataSize);
     int width = bufferWidth, height = bufferHeight;
     std::string response;
-    if (isChild)
-    {
-        Timestamp timestamp;
-
-        getLOKitDocument()->paintActiveFloatingWindow(dialogId, pixmap.data(), width, height);
-        LOG_TRC("paintActiveFloatingWindow for dialogId [" << dialogId << "] returned floating window with size "
-                << width << "X" << height << " "
-                << "rendered in " << (timestamp.elapsed()/1000.)
-                << "ms (" << (width * height) / (timestamp.elapsed()) << " MP/s).");
-
-        response = "dialogchildpaint: id=" + tokens[1] + " width=" + std::to_string(width) + " height=" + std::to_string(height) + "\n";
-    }
-    else
-    {
-        Timestamp timestamp;
-        getLOKitDocument()->paintDialog(dialogId, pixmap.data(), startX, startY, width, height);
-
-        const double area = width * height;
-        LOG_TRC("paintDialog for " << dialogId << " returned " << width << "X" << height
-                << "@(" << startX << "," << startY << ")"
-                << "and rendered in " << (timestamp.elapsed()/1000.)
-                << "ms (" << area / (timestamp.elapsed()) << " MP/s).");
+    Timestamp timestamp;
+    getLOKitDocument()->paintWindow(winId, pixmap.data(), startX, startY, width, height);
+    const double area = width * height;
+    LOG_TRC("paintWindow for " << winId << " returned " << width << "X" << height
+            << "@(" << startX << "," << startY << ")"
+            << "and rendered in " << (timestamp.elapsed()/1000.)
+            << "ms (" << area / (timestamp.elapsed()) << " MP/s).");
 
-        response = "dialogpaint: id=" + tokens[1] +
-            " width=" + std::to_string(width) + " height=" + std::to_string(height);
+    response = "windowpaint: id=" + tokens[1] +
+        " width=" + std::to_string(width) + " height=" + std::to_string(height);
 
-        if (!paintRectangle.empty())
-            response += " rectangle=" + paintRectangle;
+    if (!paintRectangle.empty())
+        response += " rectangle=" + paintRectangle;
 
-        response += "\n";
-    }
+    response += "\n";
 
     std::vector<char> output;
     output.reserve(response.size() + pixmapDataSize);
@@ -1481,11 +1456,8 @@ void ChildSession::loKitCallback(const int type, const std::string& payload)
     case LOK_CALLBACK_RULER_UPDATE:
         sendTextFrame("rulerupdate: " + payload);
         break;
-    case LOK_CALLBACK_DIALOG:
-        sendTextFrame("dialog: " + payload);
-        break;
-    case LOK_CALLBACK_DIALOG_CHILD:
-        sendTextFrame("dialogchild: " + payload);
+    case LOK_CALLBACK_WINDOW:
+        sendTextFrame("window: " + payload);
         break;
     default:
         LOG_ERR("Unknown callback event (" << type << "): " << payload);
diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp
index ad9486a2..47c79421 100644
--- a/kit/ChildSession.hpp
+++ b/kit/ChildSession.hpp
@@ -29,8 +29,7 @@ class ChildSession;
 enum class LokEventTargetEnum
 {
     Document,
-    Dialog,
-    DialogChild
+    Window
 };
 
 /// An abstract interface that defines the
@@ -194,7 +193,7 @@ private:
     bool unoCommand(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool selectText(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool selectGraphic(const char* buffer, int length, const std::vector<std::string>& tokens);
-    bool renderDialog(const char* buffer, int length, const std::vector<std::string>& tokens);
+    bool renderWindow(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool resetSelection(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool saveAs(const char* buffer, int length, const std::vector<std::string>& tokens);
     bool setClientPart(const char* buffer, int length, const std::vector<std::string>& tokens);
diff --git a/kit/Kit.cpp b/kit/Kit.cpp
index 3b373a36..ac06a8d4 100644
--- a/kit/Kit.cpp
+++ b/kit/Kit.cpp
@@ -2134,7 +2134,7 @@ void lokit_main(const std::string& childRoot,
                         TerminationFlag = true;
                     }
                     else if (tokens[0] == "tile" || tokens[0] == "tilecombine" || tokens[0] == "canceltiles" ||
-                             tokens[0] == "dialog" || tokens[0] == "dialogchild" ||
+                             tokens[0] == "paintwindow" ||
                              LOOLProtocol::getFirstToken(tokens[0], '-') == "child")
                     {
                         if (document)
diff --git a/kit/KitHelper.hpp b/kit/KitHelper.hpp
index dccf2741..f3523a9f 100644
--- a/kit/KitHelper.hpp
+++ b/kit/KitHelper.hpp
@@ -113,11 +113,8 @@ namespace LOKitHelper
             return "INVALIDATE_HEADER";
         case LOK_CALLBACK_CELL_ADDRESS:
             return "CELL_ADDRESS";
-        case LOK_CALLBACK_DIALOG:
-            return "DIALOG";
-        case LOK_CALLBACK_DIALOG_CHILD:
-            return "DIALOG_CHILD";
-
+        case LOK_CALLBACK_WINDOW:
+            return "WINDOW";
        }
 
         return std::to_string(type);
diff --git a/loleaflet/src/control/Control.LokDialog.js b/loleaflet/src/control/Control.LokDialog.js
index 1187ea4c..18e4cd24 100644
--- a/loleaflet/src/control/Control.LokDialog.js
+++ b/loleaflet/src/control/Control.LokDialog.js
@@ -8,10 +8,8 @@ L.Control.LokDialog = L.Control.extend({
 	dialogIdPrefix: 'lokdialog-',
 
 	onAdd: function (map) {
-		map.on('dialogpaint', this._onDialogPaint, this);
-		map.on('dialogchildpaint', this._onDialogChildPaint, this);
-		map.on('dialogchild', this._onDialogChildMsg, this);
-		map.on('dialog', this._onDialogMsg, this);
+		map.on('window', this._onDialogMsg, this);
+		map.on('windowpaint', this._onDialogPaint, this);
 		map.on('opendialog', this._openDialog, this);
 		map.on('docloaded', this._docLoaded, this);
 	},
@@ -25,16 +23,29 @@ L.Control.LokDialog = L.Control.extend({
 		}
 	},
 
+	_getParentDialog: function(id) {
+		for (var winId in this._dialogs) {
+			if (this._dialogs[winId].childid && this._dialogs[winId].childid === id) {
+				return winId;
+			}
+		}
+		return null;
+	},
+
 	_isOpen: function(dialogId) {
 		return this._dialogs[dialogId] &&
 			this._dialogs[dialogId].open &&
-			$('#' + dialogId).length > 0;
+			$('#' + this._toDlgPrefix(dialogId)).length > 0;
 	},
 
 	_toRawDlgId: function(dialogId) {
 		return dialogId.replace(this.dialogIdPrefix, '');
 	},
 
+	_toDlgPrefix: function(id) {
+		return this.dialogIdPrefix + id;
+	},
+
 	// Create a rectangle string of form "x,y,width,height"
 	// if params are missing, assumes 0,0,dialog width, dialog height
 	_createRectStr: function(x, y, width, height) {
@@ -50,17 +61,11 @@ L.Control.LokDialog = L.Control.extend({
 		return [x, y, width, height].join(',');
 	},
 
-	_sendDialogCommand: function(dialogId, rectangle, child) {
-		dialogId = dialogId.replace(this.dialogIdPrefix, '');
-
-		var dialogCmd = 'dialog';
-		if (child)
-			dialogCmd = 'dialogchild';
-
+	_sendWindowCommand: function(id, rectangle) {
 		if (rectangle)
 			rectangle = rectangle.replace(/ /g, '');
 
-		this._map._socket.sendMessage(dialogCmd + ' ' + dialogId + (rectangle ? ' rectangle=' + rectangle : ''));
+		this._map._socket.sendMessage('paintwindow ' + id + (rectangle ? ' rectangle=' + rectangle : ''));
 	},
 
 	_isRectangleValid: function(rect) {
@@ -71,53 +76,82 @@ L.Control.LokDialog = L.Control.extend({
 	},
 
 	_onDialogMsg: function(e) {
-		e.dialogId = this.dialogIdPrefix + e.dialogId;
+		var strDlgId = this._toDlgPrefix(e.id);
 		if (e.action === 'created') {
-			this._width = parseInt(e.size.split(',')[0]);
-			this._height = parseInt(e.size.split(',')[1]);
-			this._launchDialog(e.dialogId);
-			this._sendDialogCommand(e.dialogId, this._createRectStr());
+			var width = parseInt(e.size.split(',')[0]);
+			var height = parseInt(e.size.split(',')[1]);
+			if (e.winType === 'dialog') {
+				this._width = width;
+				this._height = height;
+				this._launchDialog(this._toDlgPrefix(e.id));
+				this._sendWindowCommand(e.id, this._createRectStr());
+			} else if (e.winType === 'child') {
+				if (!this._isOpen(e.parentId))
+					return;
+
+				var parentId = parseInt(e.parentId);
+				var left = parseInt(e.position.split(',')[0]);
+				var top = parseInt(e.position.split(',')[1]);
+
+				this._removeDialogChild(parentId);
+				this._dialogs[parentId].childid = e.id;
+				this._dialogs[parentId].childwidth = width;
+				this._dialogs[parentId].childheight = height;
+				this._dialogs[parentId].childx = left;
+				this._dialogs[parentId].childy = top;
+				this._createDialogChild(e.id, parentId, top, left);
+				this._sendWindowCommand(e.id, this._createRectStr(0, 0, width, height));
+			}
 		} else if (e.action === 'invalidate') {
-			if (this._isOpen(e.dialogId)) {
-				if (e.rectangle && !this._isRectangleValid(e.rectangle))
+			var parent = this._getParentDialog(e.id);
+			var rectangle = e.rectangle;
+			if (parent) { // this is a floating window
+				rectangle = '0,0,' + this._dialogs[parent].childwidth + ',' + this._dialogs[parent].childheight;
+			} else { // this is the actual dialog
+				if (rectangle && !this._isRectangleValid(rectangle))
 					return;
 
-				if (!e.rectangle)
-					e.rectangle = '0,0,' + this._width + ',' + this._height;
-				this._sendDialogCommand(e.dialogId, e.rectangle);
+				if (!rectangle)
+					rectangle = '0,0,' + this._width + ',' + this._height;
 			}
+			this._sendWindowCommand(e.id, rectangle);
 		} else if (e.action === 'size_changed') {
 			this._width = parseInt(e.size.split(',')[0]);
 			this._height = parseInt(e.size.split(',')[1]);
 
+			strDlgId = this._toDlgPrefix(e.id);
 			// FIXME: we don't really have to destroy and launch the dialog again but do it for
 			// now because the size sent to us previously in 'created' cb is not correct
-			$('#' + e.dialogId).remove();
-			this._launchDialog(e.dialogId);
-			$('#' + e.dialogId).dialog('option', 'title', this._title);
-			this._sendDialogCommand(e.dialogId, this._createRectStr());
+			$('#' + strDlgId).remove();
+			this._launchDialog(strDlgId);
+			$('#' + strDlgId).dialog('option', 'title', this._title);
+			this._sendWindowCommand(e.id, this._createRectStr());
 		} else if (e.action === 'cursor_invalidate') {
-			if (this._isOpen(e.dialogId) && !!e.rectangle) {
+			if (this._isOpen(e.id) && !!e.rectangle) {
 				var rectangle = e.rectangle.split(',');
 				var x = parseInt(rectangle[0]);
 				var y = parseInt(rectangle[1]);
 				var height = parseInt(rectangle[3]);
 
-				$('#' + e.dialogId + '-cursor').css({height: height});
+				$('#' + strDlgId + '-cursor').css({height: height});
 				// set the position of the lokdialog-cursor
-				$(this._dialogs[e.dialogId].cursor).css({left: x, top: y});
+				$(this._dialogs[e.id].cursor).css({left: x, top: y});
 			}
 		} else if (e.action === 'title_changed') {
 			this._title = e.title;
-			$('#' + e.dialogId).dialog('option', 'title', e.title);
+			$('#' + strDlgId).dialog('option', 'title', e.title);
 		} else if (e.action === 'cursor_visible') {
 			var visible = e.visible === 'true';
 			if (visible)
-				$('#' + e.dialogId + '-cursor').css({display: 'block'});
+				$('#' + strDlgId + '-cursor').css({display: 'block'});
 			else
-				$('#' + e.dialogId + '-cursor').css({display: 'none'});
+				$('#' + strDlgId + '-cursor').css({display: 'none'});
 		} else if (e.action === 'close') {
-			this._onDialogClose(e.dialogId);
+			parent = this._getParentDialog(e.id);
+			if (parent)
+				this._onDialogChildClose(this._toDlgPrefix(parent));
+			else
+				this._onDialogClose(e.id);
 		}
 	},
 
@@ -126,19 +160,20 @@ L.Control.LokDialog = L.Control.extend({
 	},
 
 	_launchDialogCursor: function(dialogId) {
-		this._dialogs[dialogId].cursor = L.DomUtil.create('div', 'leaflet-cursor-container', L.DomUtil.get(dialogId));
-		var cursor = L.DomUtil.create('div', 'leaflet-cursor lokdialog-cursor', this._dialogs[dialogId].cursor);
+		var id = this._toRawDlgId(dialogId);
+		this._dialogs[id].cursor = L.DomUtil.create('div', 'leaflet-cursor-container', L.DomUtil.get(dialogId));
+		var cursor = L.DomUtil.create('div', 'leaflet-cursor lokdialog-cursor', this._dialogs[id].cursor);
 		cursor.id = dialogId + '-cursor';
 		L.DomUtil.addClass(cursor, 'blinking-cursor');
 	},
 
-	_launchDialog: function(dialogId) {
-		var canvas = '<div class="lokdialog" style="padding: 0px; margin: 0px; overflow: hidden;" id="' + dialogId + '">' +
-		    '<canvas class="lokdialog_canvas" tabindex="0" id="' + dialogId + '-canvas" width="' + this._width + 'px" height="' + this._height + 'px"></canvas>' +
+	_launchDialog: function(strDlgId) {
+		var canvas = '<div class="lokdialog" style="padding: 0px; margin: 0px; overflow: hidden;" id="' + strDlgId + '">' +
+		    '<canvas class="lokdialog_canvas" tabindex="0" id="' + strDlgId + '-canvas" width="' + this._width + 'px" height="' + this._height + 'px"></canvas>' +
 		    '</div>';
 		$(document.body).append(canvas);
 		var that = this;
-		$('#' + dialogId).dialog({
+		$('#' + strDlgId).dialog({
 			width: this._width,
 			title: 'LOK Dialog', // TODO: Get the 'real' dialog title from the backend
 			modal: false,
@@ -146,59 +181,53 @@ L.Control.LokDialog = L.Control.extend({
 			resizable: false,
 			dialogClass: 'lokdialog_container',
 			close: function() {
-				that._onDialogClose(dialogId);
+				that._onDialogClose(strDlgId);
 			}
 		});
 
-		this._dialogs[dialogId] = { open: true };
+		this._dialogs[this._toRawDlgId(strDlgId)] = { open: true };
 
 		// don't make 'TAB' focus on this button; we want to cycle focus in the lok dialog with each TAB
 		$('.lokdialog_container button.ui-dialog-titlebar-close').attr('tabindex', '-1').blur();
 
-		$('#' + dialogId + '-canvas').on('mousedown', function(e) {
+		$('#' + strDlgId + '-canvas').on('mousedown', function(e) {
 			var buttons = 0;
 			buttons |= e.button === map['mouse'].JSButtons.left ? map['mouse'].LOButtons.left : 0;
 			buttons |= e.button === map['mouse'].JSButtons.middle ? map['mouse'].LOButtons.middle : 0;
 			buttons |= e.button === map['mouse'].JSButtons.right ? map['mouse'].LOButtons.right : 0;
 			var modifier = 0;
-			that._postDialogMouseEvent('buttondown', dialogId, e.offsetX, e.offsetY, 1, buttons, modifier);
+			that._postWindowMouseEvent('buttondown', strDlgId, e.offsetX, e.offsetY, 1, buttons, modifier);
 		});
-		$('#' + dialogId + '-canvas').on('mouseup', function(e) {
+		$('#' + strDlgId + '-canvas').on('mouseup', function(e) {
 			var buttons = 0;
 			buttons |= e.button === map['mouse'].JSButtons.left ? map['mouse'].LOButtons.left : 0;
 			buttons |= e.button === map['mouse'].JSButtons.middle ? map['mouse'].LOButtons.middle : 0;
 			buttons |= e.button === map['mouse'].JSButtons.right ? map['mouse'].LOButtons.right : 0;
 			var modifier = 0;
-			that._postDialogMouseEvent('buttonup', dialogId, e.offsetX, e.offsetY, 1, buttons, modifier);
+			that._postWindowMouseEvent('buttonup', strDlgId, e.offsetX, e.offsetY, 1, buttons, modifier);
 		});
-		$('#' + dialogId + '-canvas').on('keyup keypress keydown', function(e) {
-			e.dialogId = dialogId;
+		$('#' + strDlgId + '-canvas').on('keyup keypress keydown', function(e) {
+			e.strDlgId = strDlgId;
 			that._handleDialogKeyEvent(e);
 		});
-		$('#' + dialogId + '-canvas').on('contextmenu', function() {
+		$('#' + strDlgId + '-canvas').on('contextmenu', function() {
 			return false;
 		});
 
-		this._launchDialogCursor(dialogId);
+		this._launchDialogCursor(strDlgId);
 	},
 
-	_postDialogMouseEvent: function(type, dialogid, x, y, count, buttons, modifier) {
-		this._map._socket.sendMessage('dialogmouse dialogid=' + this._toRawDlgId(dialogid) +  ' type=' + type +
+	_postWindowMouseEvent: function(type, winid, x, y, count, buttons, modifier) {
+		this._map._socket.sendMessage('windowmouse id=' + this._toRawDlgId(winid) +  ' type=' + type +
 		                              ' x=' + x + ' y=' + y + ' count=' + count +
 		                              ' buttons=' + buttons + ' modifier=' + modifier);
 	},
 
-	_postDialogKeyboardEvent: function(type, dialogid, charcode, keycode) {
-		this._map._socket.sendMessage('dialogkey dialogid=' + this._toRawDlgId(dialogid) + ' type=' + type +
+	_postWindowKeyboardEvent: function(type, winid, charcode, keycode) {
+		this._map._socket.sendMessage('windowkey id=' + this._toRawDlgId(winid) + ' type=' + type +
 		                              ' char=' + charcode + ' key=' + keycode);
 	},
 
-	_postDialogChildMouseEvent: function(type, dialogid, x, y, count, buttons, modifier) {
-		this._map._socket.sendMessage('dialogchildmouse dialogid=' + this._toRawDlgId(dialogid) +  ' type=' + type +
-		                              ' x=' + x + ' y=' + y + ' count=' + count +
-		                              ' buttons=' + buttons + ' modifier=' + modifier);
-	},
-
 	_handleDialogKeyEvent: function(e) {
 		this.modifier = 0;
 		var shift = e.originalEvent.shiftKey ? this._map['keyboard'].keyModifier.shift : 0;
@@ -214,38 +243,39 @@ L.Control.LokDialog = L.Control.extend({
 		if (this.modifier) {
 			unoKeyCode |= this.modifier;
 			if (e.type !== 'keyup') {
-				this._postDialogKeyboardEvent('input', e.dialogId, charCode, unoKeyCode);
+				this._postWindowKeyboardEvent('input', e.strDlgId, charCode, unoKeyCode);
 				return;
 			}
 		}
 
 		if (e.type === 'keydown' && this._map['keyboard'].handleOnKeyDownKeys[keyCode]) {
-			this._postDialogKeyboardEvent('input', e.dialogId, charCode, unoKeyCode);
+			this._postWindowKeyboardEvent('input', e.strDlgId, charCode, unoKeyCode);
 		}
 		else if (e.type === 'keypress' && (!this._map['keyboard'].handleOnKeyDownKeys[keyCode] || charCode !== 0)) {
 			if (charCode === keyCode && charCode !== 13) {
 				keyCode = 0;
 				unoKeyCode = this._map['keyboard']._toUNOKeyCode(keyCode);
 			}
-			this._postDialogKeyboardEvent('input', e.dialogId, charCode, unoKeyCode);
+			this._postWindowKeyboardEvent('input', e.strDlgId, charCode, unoKeyCode);
 		}
 		else if (e.type === 'keyup') {
-			this._postDialogKeyboardEvent('up', e.dialogId, charCode, unoKeyCode);
+			this._postWindowKeyboardEvent('up', e.strDlgId, charCode, unoKeyCode);
 		}
 	},
 
 	_onDialogClose: function(dialogId) {
-		$('#' + dialogId).remove();
+		$('#' + this._toDlgPrefix(dialogId)).remove();
 		this._map.focus();
 		delete this._dialogs[dialogId];
 	},
 
-	_paintDialog: function(dialogId, title, rectangle, imgData) {
+	_paintDialog: function(dialogId, rectangle, imgData) {
 		if (!this._isOpen(dialogId))
 			return;
 
+		var strDlgId = this._toDlgPrefix(dialogId);
 		var img = new Image();
-		var canvas = document.getElementById(dialogId + '-canvas');
+		var canvas = document.getElementById(strDlgId + '-canvas');
 		var ctx = canvas.getContext('2d');
 		img.onload = function() {
 			var x = 0;
@@ -263,34 +293,35 @@ L.Control.LokDialog = L.Control.extend({
 
 	// Binary dialog msg recvd from core
 	_onDialogPaint: function (e) {
-		var dialogId = this.dialogIdPrefix + e.id;
-		if (!this._isOpen(dialogId))
-			return;
-
-		this._paintDialog(dialogId, e.title, e.rectangle, e.dialog);
+		var parent = this._getParentDialog(e.id);
+		if (parent) {
+			this._paintDialogChild(parent, e.width, e.height, e.rectangle, e.img);
+		} else {
+			this._paintDialog(e.id, e.rectangle, e.img);
+		}
 	},
 
 	// Dialog Child Methods
 
-	_onDialogChildPaint: function(e) {
-		var dialogId = this.dialogIdPrefix + e.id;
+	_paintDialogChild: function(dialogId, width, height, rectangle, imgData) {
+		var strDlgId = this._toDlgPrefix(dialogId);
 		var img = new Image();
-		var canvas = document.getElementById(dialogId + '-floating');
-		canvas.width = e.width;
-		canvas.height = e.height;
+		var canvas = document.getElementById(strDlgId + '-floating');
+		canvas.width = width;
+		canvas.height = height;
 		var ctx = canvas.getContext('2d');
 		img.onload = function() {
 			ctx.drawImage(img, 0, 0);
 		};
-		img.src = e.dialog;
+		img.src = imgData;
 
 		// increase the height of the container,
 		// so that if the floating window goes out of the parent,
 		// it doesn't get stripped off
-		var height = parseInt(canvas.style.top) + canvas.height;
-		var currentHeight = parseInt($('#' + dialogId).css('height'));
+		height = parseInt(canvas.style.top) + canvas.height;
+		var currentHeight = parseInt($('#' + strDlgId).css('height'));
 		if (height > currentHeight)
-			$('#' + dialogId).css('height', height + 'px');
+			$('#' + strDlgId).css('height', height + 'px');
 	},
 
 	_onDialogChildClose: function(dialogId) {
@@ -300,87 +331,43 @@ L.Control.LokDialog = L.Control.extend({
 		$('#' + dialogId).height(canvasHeight + 'px');
 	},
 
-	_isDialogChildUnchanged: function(dialogId, left, top) {
-		// get pervious dialog child's specs
-		var oldLeft = $('#' + dialogId + '-floating').css('left');
-		var oldTop = $('#' + dialogId + '-floating').css('top');
-		if (!oldLeft || !oldTop) {
-			// no left or top position set earlier; this is first dialog child placement
-			return false;
-		}
-
-		oldLeft = parseInt(oldLeft);
-		oldTop = parseInt(oldTop);
-		if (oldLeft !== left || oldTop !== top) {
-			// something changed in new dialog child
-			return false;
-		}
-
-		return true;
-	},
-
-	_removeDialogChild: function(dialogId) {
-		$('#' + dialogId + '-floating').remove();
+	_removeDialogChild: function(id) {
+		$('#' + id + '-floating').remove();
 	},
 
-	_createDialogChild: function(dialogId, top, left) {
-		var floatingCanvas = '<canvas class="lokdialogchild-canvas" id="' + dialogId + '-floating"></canvas>';
-		$('#' + dialogId).append(floatingCanvas);
-		$('#' + dialogId + '-floating').css({position: 'absolute', left: left, top: top});
+	_createDialogChild: function(childId, dialogId, top, left) {
+		var strDlgId = this._toDlgPrefix(dialogId);
+		var floatingCanvas = '<canvas class="lokdialogchild-canvas" id="' + strDlgId + '-floating"></canvas>';
+		$('#' + strDlgId).append(floatingCanvas);
+		$('#' + strDlgId + '-floating').css({position: 'absolute', left: left, top: top});
 
 		var that = this;
 		// attach events
-		$('#' + dialogId + '-floating').on('mousedown', function(e) {
+		$('#' + strDlgId + '-floating').on('mousedown', function(e) {
 			var buttons = 0;
 			buttons |= e.button === map['mouse'].JSButtons.left ? map['mouse'].LOButtons.left : 0;
 			buttons |= e.button === map['mouse'].JSButtons.middle ? map['mouse'].LOButtons.middle : 0;
 			buttons |= e.button === map['mouse'].JSButtons.right ? map['mouse'].LOButtons.right : 0;
 			var modifier = 0;
-			that._postDialogChildMouseEvent('buttondown', dialogId, e.offsetX, e.offsetY, 1, buttons, modifier);
+			that._postWindowMouseEvent('buttondown', childId, e.offsetX, e.offsetY, 1, buttons, modifier);
 		});
 
-		$('#' + dialogId + '-floating').on('mouseup', function(e) {
+		$('#' + strDlgId + '-floating').on('mouseup', function(e) {
 			var buttons = 0;
 			buttons |= e.button === map['mouse'].JSButtons.left ? map['mouse'].LOButtons.left : 0;
 			buttons |= e.button === map['mouse'].JSButtons.middle ? map['mouse'].LOButtons.middle : 0;
 			buttons |= e.button === map['mouse'].JSButtons.right ? map['mouse'].LOButtons.right : 0;
 			var modifier = 0;
-			that._postDialogChildMouseEvent('buttonup', dialogId, e.offsetX, e.offsetY, 1, buttons, modifier);
+			that._postWindowMouseEvent('buttonup', childId, e.offsetX, e.offsetY, 1, buttons, modifier);
 		});
 
-		$('#' + dialogId + '-floating').on('mousemove', function(e) {
-			that._postDialogChildMouseEvent('move', dialogId, e.offsetX, e.offsetY, 1, 0, 0);
+		$('#' + strDlgId + '-floating').on('mousemove', function(e) {
+			that._postWindowMouseEvent('move', childId, e.offsetX, e.offsetY, 1, 0, 0);
 		});
 
-		$('#' + dialogId + '-floating').on('contextmenu', function() {
+		$('#' + strDlgId + '-floating').on('contextmenu', function() {
 			return false;
 		});
-	},
-
-	_launchDialogChildIfRequired: function(e) {
-		var positions = e.position.split(',');
-		var left = parseInt(positions[0]);
-		var top = parseInt(positions[1]);
-
-		if (e.position === '0, 0' || // FIXME: we get incorrect "0, 0" position for floating windows as first message
-		    this._isDialogChildUnchanged(e.dialogId, left, top)) // no need to create the html element; we can just repaint it
-			return;
-
-		this._removeDialogChild(e.dialogId);
-		this._createDialogChild(e.dialogId, top, left);
-	},
-
-	_onDialogChildMsg: function(e) {
-		e.dialogId = this.dialogIdPrefix + e.dialogId;
-		if (e.action === 'invalidate') {
-			if (this._isOpen(e.dialogId))
-			{
-				this._sendDialogCommand(e.dialogId, false /* no json */, true /* dialog child*/);
-				this._launchDialogChildIfRequired(e);
-			}
-		} else if (e.action === 'close') {
-			this._onDialogChildClose(e.dialogId);
-		}
 	}
 });
 
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index 36c75624..fb814ef2 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -608,7 +608,7 @@ L.Socket = L.Class.extend({
 				}
 			}
 		}
-		else if (!textMsg.startsWith('tile:') && !textMsg.startsWith('renderfont:') && !textMsg.startsWith('dialogpaint:') && !textMsg.startsWith('dialogchildpaint:')) {
+		else if (!textMsg.startsWith('tile:') && !textMsg.startsWith('renderfont:') && !textMsg.startsWith('windowpaint:')) {
 			// log the tile msg separately as we need the tile coordinates
 			L.Log.log(textMsg, L.INCOMING);
 
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index d704368e..fa01615d 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -449,18 +449,12 @@ L.TileLayer = L.GridLayer.extend({
 		else if (textMsg.startsWith('tile:')) {
 			this._onTileMsg(textMsg, img);
 		}
-		else if (textMsg.startsWith('dialogpaint:')) {
+		else if (textMsg.startsWith('windowpaint:')) {
 			this._onDialogPaintMsg(textMsg, img);
 		}
-		else if (textMsg.startsWith('dialogchildpaint:')) {
-			this._onDialogChildPaintMsg(textMsg, img);
-		}
-		else if (textMsg.startsWith('dialog:')) {
+		else if (textMsg.startsWith('window:')) {
 			this._onDialogMsg(textMsg);
 		}
-		else if (textMsg.startsWith('dialogchild:')) {
-			this._onDialogChildMsg(textMsg);
-		}
 		else if (textMsg.startsWith('unocommandresult:')) {
 			this._onUnoCommandResultMsg(textMsg);
 		}
@@ -1207,41 +1201,21 @@ L.TileLayer = L.GridLayer.extend({
 	_onDialogPaintMsg: function(textMsg, img) {
 		var command = this._map._socket.parseServerCmd(textMsg);
 
-		this._map.fire('dialogpaint', {
+		this._map.fire('windowpaint', {
 			id: command.id,
-			dialog: img,
-			title: command.title,
-			// TODO: add id too
+			img: img,
 			width: command.width,
 			height: command.height,
 			rectangle: command.rectangle
 		});
 	},
 
-	_onDialogChildPaintMsg: function(textMsg, img) {
-		var command = this._map._socket.parseServerCmd(textMsg);
-		var width = command.width;
-		var height = command.height;
-
-		this._map.fire('dialogchildpaint', {
-			id: command.id,
-			dialog: img,
-			// TODO: add id too
-			width: width,
-			height: height
-		});
-	},
-
 	_onDialogMsg: function(textMsg) {
-		textMsg = textMsg.substring('dialog: '.length);
-		var dialogMsg = JSON.parse(textMsg);
-		this._map.fire('dialog', dialogMsg);
-	},
-
-	_onDialogChildMsg: function(textMsg) {
-		textMsg = textMsg.substring('dialogchild: '.length);
+		textMsg = textMsg.substring('window: '.length);
 		var dialogMsg = JSON.parse(textMsg);
-		this._map.fire('dialogchild', dialogMsg);
+		// e.type refers to signal type
+		dialogMsg.winType = dialogMsg.type;
+		this._map.fire('window', dialogMsg);
 	},
 
 	_onTileMsg: function (textMsg, img) {
diff --git a/tools/KitClient.cpp b/tools/KitClient.cpp
index 98ee4d9f..4357907c 100644
--- a/tools/KitClient.cpp
+++ b/tools/KitClient.cpp
@@ -79,8 +79,7 @@ extern "C"
             CASE(INVALIDATE_HEADER);
             CASE(CELL_ADDRESS);
             CASE(RULER_UPDATE);
-            CASE(DIALOG);
-            CASE(DIALOG_CHILD);
+            CASE(WINDOW);
 #undef CASE
         }
         std::cout << " payload: " << payload << std::endl;
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 663a55fc..b607ed0f 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -135,10 +135,9 @@ bool ClientSession::_handleInput(const char *buffer, int length)
              tokens[0] != "paste" &&
              tokens[0] != "insertfile" &&
              tokens[0] != "key" &&
-             tokens[0] != "dialogkey" &&
+             tokens[0] != "windowkey" &&
              tokens[0] != "mouse" &&
-             tokens[0] != "dialogmouse" &&
-             tokens[0] != "dialogchildmouse" &&
+             tokens[0] != "windowmouse" &&
              tokens[0] != "partpagerectangles" &&
              tokens[0] != "ping" &&
              tokens[0] != "renderfont" &&
@@ -157,8 +156,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
              tokens[0] != "uno" &&
              tokens[0] != "useractive" &&
              tokens[0] != "userinactive" &&
-             tokens[0] != "dialog" &&
-             tokens[0] != "dialogchild")
+             tokens[0] != "paintwindow")
     {
         sendTextFrame("error: cmd=" + tokens[0] + " kind=unknown");
         return false;


More information about the Libreoffice-commits mailing list