[Libreoffice-commits] online.git: kit/ChildSession.cpp wsd/ClientSession.cpp wsd/ClientSession.hpp
Dennis Francis (via logerrit)
logerrit at kemper.freedesktop.org
Wed Jul 8 15:18:53 UTC 2020
kit/ChildSession.cpp | 2
wsd/ClientSession.cpp | 156 ++++++++++++++++++++++++++++++++++++++++++--------
wsd/ClientSession.hpp | 20 ++++++
3 files changed, 153 insertions(+), 25 deletions(-)
New commits:
commit d1b3f4c6af35849e0da7a1148a88f183a4e1101f
Author: Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Wed Jul 8 07:10:13 2020 +0530
Commit: Dennis Francis <dennis.francis at collabora.com>
CommitDate: Wed Jul 8 17:18:33 2020 +0200
wsd/kit: use splitx/splity in clientvisiblearea message...
to filter tile-invalidation messages, so that the client gets
invalidations/new tiles for all split panes.
Change-Id: Ifacc452ed6bb43dfd36ff16386fb4a547ec8302b
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/98362
Tested-by: Jenkins
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Dennis Francis <dennis.francis at collabora.com>
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index c2644e68a..39b9d3b41 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -850,7 +850,7 @@ bool ChildSession::clientVisibleArea(const char* /*buffer*/, int /*length*/, con
int width;
int height;
- if (tokens.size() != 5 ||
+ if ((tokens.size() != 5 && tokens.size() != 7) ||
!getTokenInteger(tokens[1], "x", x) ||
!getTokenInteger(tokens[2], "y", y) ||
!getTokenInteger(tokens[3], "width", width) ||
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index b313742ec..abed4c5df 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -58,6 +58,8 @@ ClientSession::ClientSession(
_state(SessionState::DETACHED),
_keyEvents(1),
_clientVisibleArea(0, 0, 0, 0),
+ _splitX(0),
+ _splitY(0),
_clientSelectedPart(-1),
_tileWidthPixel(0),
_tileHeightPixel(0),
@@ -571,7 +573,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
int y;
int width;
int height;
- if (tokens.size() != 5 ||
+ if ((tokens.size() != 5 && tokens.size() != 7) ||
!getTokenInteger(tokens[1], "x", x) ||
!getTokenInteger(tokens[2], "y", y) ||
!getTokenInteger(tokens[3], "width", width) ||
@@ -584,6 +586,20 @@ bool ClientSession::_handleInput(const char *buffer, int length)
}
else
{
+ if (tokens.size() == 7)
+ {
+ int splitX, splitY;
+ if (!getTokenInteger(tokens[5], "splitx", splitX) ||
+ !getTokenInteger(tokens[6], "splity", splitY))
+ {
+ LOG_WRN("Invalid syntax for '" << tokens[0] << "' message: [" << firstLine << "].");
+ return true;
+ }
+
+ _splitX = splitX;
+ _splitY = splitY;
+ }
+
_clientVisibleArea = Util::Rectangle(x, y, width, height);
resetWireIdMap();
return forwardToChild(std::string(buffer, length), docBroker);
@@ -1732,15 +1748,31 @@ void ClientSession::handleTileInvalidation(const std::string& message,
return;
}
- // Visible area can have negative value as position, but we have tiles only in the positive range
- Util::Rectangle normalizedVisArea = getNormalizedVisibleArea();
-
std::pair<int, Util::Rectangle> result = TileCache::parseInvalidateMsg(message);
int part = result.first;
Util::Rectangle& invalidateRect = result.second;
- // We can ignore the invalidation if it's outside of the visible area
- if(!normalizedVisArea.intersects(invalidateRect))
+ constexpr SplitPaneName panes[4] = {
+ TOPLEFT_PANE,
+ TOPRIGHT_PANE,
+ BOTTOMLEFT_PANE,
+ BOTTOMRIGHT_PANE
+ };
+ Util::Rectangle paneRects[4];
+ int numPanes = 0;
+ for(int i = 0; i < 4; ++i)
+ {
+ if(!isSplitPane(panes[i]))
+ continue;
+
+ Util::Rectangle rect = getNormalizedVisiblePaneArea(panes[i]);
+ if (rect.intersects(invalidateRect)) {
+ paneRects[numPanes++] = rect;
+ }
+ }
+
+ // We can ignore the invalidation if it's outside of all split-panes.
+ if(!numPanes)
return;
if( part == -1 ) // If no part is specified we use the part used by the client
@@ -1751,26 +1783,30 @@ void ClientSession::handleTileInvalidation(const std::string& message,
std::vector<TileDesc> invalidTiles;
if(part == _clientSelectedPart || _isTextDocument)
{
- // Iterate through visible tiles
- for(int i = std::ceil(normalizedVisArea.getTop() / _tileHeightTwips);
- i <= std::ceil(normalizedVisArea.getBottom() / _tileHeightTwips); ++i)
+ for(int paneIdx = 0; paneIdx < numPanes; ++paneIdx)
{
- for(int j = std::ceil(normalizedVisArea.getLeft() / _tileWidthTwips);
- j <= std::ceil(normalizedVisArea.getRight() / _tileWidthTwips); ++j)
+ const Util::Rectangle& normalizedVisArea = paneRects[paneIdx];
+ // Iterate through visible tiles
+ for(int i = std::ceil(normalizedVisArea.getTop() / _tileHeightTwips);
+ i <= std::ceil(normalizedVisArea.getBottom() / _tileHeightTwips); ++i)
{
- // Find tiles affected by invalidation
- Util::Rectangle tileRect (j * _tileWidthTwips, i * _tileHeightTwips, _tileWidthTwips, _tileHeightTwips);
- if(invalidateRect.intersects(tileRect))
+ for(int j = std::ceil(normalizedVisArea.getLeft() / _tileWidthTwips);
+ j <= std::ceil(normalizedVisArea.getRight() / _tileWidthTwips); ++j)
{
- invalidTiles.emplace_back(normalizedViewId, part, _tileWidthPixel, _tileHeightPixel, j * _tileWidthTwips, i * _tileHeightTwips, _tileWidthTwips, _tileHeightTwips, -1, 0, -1, false);
+ // Find tiles affected by invalidation
+ Util::Rectangle tileRect (j * _tileWidthTwips, i * _tileHeightTwips, _tileWidthTwips, _tileHeightTwips);
+ if(invalidateRect.intersects(tileRect))
+ {
+ invalidTiles.emplace_back(normalizedViewId, part, _tileWidthPixel, _tileHeightPixel, j * _tileWidthTwips, i * _tileHeightTwips, _tileWidthTwips, _tileHeightTwips, -1, 0, -1, false);
- TileWireId oldWireId = 0;
- auto iter = _oldWireIds.find(invalidTiles.back().generateID());
- if(iter != _oldWireIds.end())
- oldWireId = iter->second;
+ TileWireId oldWireId = 0;
+ auto iter = _oldWireIds.find(invalidTiles.back().generateID());
+ if(iter != _oldWireIds.end())
+ oldWireId = iter->second;
- invalidTiles.back().setOldWireId(oldWireId);
- invalidTiles.back().setWireId(0);
+ invalidTiles.back().setOldWireId(oldWireId);
+ invalidTiles.back().setWireId(0);
+ }
}
}
}
@@ -1784,6 +1820,80 @@ void ClientSession::handleTileInvalidation(const std::string& message,
}
}
+bool ClientSession::isSplitPane(const SplitPaneName paneName) const
+{
+ if (paneName == BOTTOMRIGHT_PANE)
+ return true;
+
+ if (paneName == TOPLEFT_PANE)
+ return (_splitX && _splitY);
+
+ if (paneName == TOPRIGHT_PANE)
+ return _splitY;
+
+ if (paneName == BOTTOMLEFT_PANE)
+ return _splitX;
+
+ return false;
+}
+
+Util::Rectangle ClientSession::getNormalizedVisiblePaneArea(const SplitPaneName paneName) const
+{
+ Util::Rectangle normalizedVisArea = getNormalizedVisibleArea();
+ if (!_splitX && !_splitY)
+ return paneName == BOTTOMRIGHT_PANE ? normalizedVisArea : Util::Rectangle();
+
+ int freeStartX = normalizedVisArea.getLeft() + _splitX;
+ int freeStartY = normalizedVisArea.getTop() + _splitY;
+ int freeWidth = normalizedVisArea.getWidth() - _splitX;
+ int freeHeight = normalizedVisArea.getHeight() - _splitY;
+
+ switch (paneName)
+ {
+ case BOTTOMRIGHT_PANE:
+ return Util::Rectangle(freeStartX, freeStartY, freeWidth, freeHeight);
+ case TOPLEFT_PANE:
+ return (_splitX && _splitY) ? Util::Rectangle(0, 0, _splitX, _splitY) : Util::Rectangle();
+ case TOPRIGHT_PANE:
+ return _splitY ? Util::Rectangle(freeStartX, 0, freeWidth, _splitY) : Util::Rectangle();
+ case BOTTOMLEFT_PANE:
+ return _splitX ? Util::Rectangle(0, freeStartY, _splitX, freeHeight) : Util::Rectangle();
+ default:
+ assert(false && "Unknown split-pane name");
+ }
+
+ return Util::Rectangle();
+}
+
+bool ClientSession::isTileInsideVisibleArea(const TileDesc& tile) const
+{
+ if (!_splitX && !_splitY)
+ {
+ return (tile.getTilePosX() >= _clientVisibleArea.getLeft() && tile.getTilePosX() <= _clientVisibleArea.getRight() &&
+ tile.getTilePosY() >= _clientVisibleArea.getTop() && tile.getTilePosY() <= _clientVisibleArea.getBottom());
+ }
+
+ constexpr SplitPaneName panes[4] = {
+ TOPLEFT_PANE,
+ TOPRIGHT_PANE,
+ BOTTOMLEFT_PANE,
+ BOTTOMRIGHT_PANE
+ };
+
+ for (int i = 0; i < 4; ++i)
+ {
+ if (!isSplitPane(panes[i]))
+ continue;
+
+ Util::Rectangle paneRect = getNormalizedVisiblePaneArea(panes[i]);
+ if (tile.getTilePosX() >= paneRect.getLeft() && tile.getTilePosX() <= paneRect.getRight() &&
+ tile.getTilePosY() >= paneRect.getTop() && tile.getTilePosY() <= paneRect.getBottom())
+ return true;
+ }
+
+ return false;
+}
+
void ClientSession::resetWireIdMap()
{
_oldWireIds.clear();
@@ -1802,9 +1912,7 @@ void ClientSession::traceTileBySend(const TileDesc& tile, bool deduplicated)
else
{
// Track only tile inside the visible area
- if(_clientVisibleArea.hasSurface() &&
- tile.getTilePosX() >= _clientVisibleArea.getLeft() && tile.getTilePosX() <= _clientVisibleArea.getRight() &&
- tile.getTilePosY() >= _clientVisibleArea.getTop() && tile.getTilePosY() <= _clientVisibleArea.getBottom())
+ if(_clientVisibleArea.hasSurface() && isTileInsideVisibleArea(tile))
{
_oldWireIds.insert(std::pair<std::string, TileWireId>(tileID, tile.getWireId()));
}
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index cc153bdd8..6304cd4a9 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -138,6 +138,20 @@ public:
/// Visible area can have negative value as position, but we have tiles only in the positive range
Util::Rectangle getNormalizedVisibleArea() const;
+ /// The client's visible area can be divided into a maximum of 4 panes.
+ enum SplitPaneName {
+ TOPLEFT_PANE,
+ TOPRIGHT_PANE,
+ BOTTOMLEFT_PANE,
+ BOTTOMRIGHT_PANE
+ };
+
+ /// Returns true if the given split-pane is currently valid.
+ bool isSplitPane(const SplitPaneName) const;
+
+ /// Returns the normalized visible area of a given split-pane.
+ Util::Rectangle getNormalizedVisiblePaneArea(const SplitPaneName) const;
+
int getTileWidthInTwips() const { return _tileWidthTwips; }
int getTileHeightInTwips() const { return _tileHeightTwips; }
@@ -220,6 +234,8 @@ private:
void handleTileInvalidation(const std::string& message,
const std::shared_ptr<DocumentBroker>& docBroker);
+ bool isTileInsideVisibleArea(const TileDesc& tile) const;
+
private:
std::weak_ptr<DocumentBroker> _docBroker;
@@ -255,6 +271,10 @@ private:
/// Visible area of the client
Util::Rectangle _clientVisibleArea;
+ /// Split position that defines the current split panes
+ int _splitX;
+ int _splitY;
+
/// Selected part of the document viewed by the client (no parts in Writer)
int _clientSelectedPart;
More information about the Libreoffice-commits
mailing list