vcl: cursor invalidation for form controls
Form controls need to send cursor invalidation when, to make it possible to show the cursor in online, when we are editing an edit box in the document. Change-Id: I17c74b8183ba8caf06898019908bf0c2879d49d0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189178 Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190804 Tested-by: Jenkins Reviewed-by: Gökay ŞATIR <gokaysatir@collabora.com>
This commit is contained in:
committed by
Gökay ŞATIR
parent
7a036a6458
commit
0b18630a51
@@ -53,7 +53,8 @@
|
||||
#include <sal/log.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <vcl/window.hxx>
|
||||
#include <toolkit/helper/vclunohelper.hxx>
|
||||
namespace frm
|
||||
{
|
||||
using namespace ::com::sun::star::uno;
|
||||
@@ -270,6 +271,9 @@ void SAL_CALL OControl::createPeer(const Reference<XToolkit>& _rxToolkit, const
|
||||
{
|
||||
m_xControl->createPeer( _rxToolkit, _rxParent );
|
||||
impl_resetStateGuard_nothrow();
|
||||
|
||||
VclPtr<vcl::Window> pVclPeer = VCLUnoHelper::GetWindow(getPeer());
|
||||
pVclPeer->SetFormControl(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,8 @@ public:
|
||||
static void notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable* pDoc, bool bInvalidateAll = true);
|
||||
/// Emits a LOK_CALLBACK_DOCUMENT_SIZE_CHANGED for all views of the same document with the same part
|
||||
static void notifyPartSizeChangedAllViews(vcl::ITiledRenderable* pDoc, int nPart);
|
||||
/// Emits a LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR
|
||||
static void notifyCursorInvalidation(SfxViewShell const* pThisView, tools::Rectangle const * pRect, bool bControlEvent);
|
||||
/// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
|
||||
static void notifyInvalidation(SfxViewShell const* pThisView, int nPart, tools::Rectangle const *);
|
||||
/// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed
|
||||
|
||||
@@ -434,6 +434,9 @@ public:
|
||||
|
||||
/// ILibreOfficeKitNotifier. Emits a LOK_CALLBACK_INVALIDATE_TILES.
|
||||
virtual void notifyInvalidation(tools::Rectangle const *) const override;
|
||||
/// ILibreOfficeKitNotifier.
|
||||
virtual void notifyCursorInvalidation(tools::Rectangle const *, bool bControlEvent) const override;
|
||||
|
||||
/// See OutlinerViewShell::NotifyOtherViews().
|
||||
void NotifyOtherViews(int nType, const OString& rKey, const OString& rPayload) override;
|
||||
/// See OutlinerViewShell::NotifyOtherView().
|
||||
|
||||
@@ -40,6 +40,9 @@ public:
|
||||
/// Emits a LOK_CALLBACK_INVALIDATE_TILES.
|
||||
virtual void notifyInvalidation(tools::Rectangle const *) const = 0;
|
||||
|
||||
/// Emits a LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR.
|
||||
virtual void notifyCursorInvalidation(tools::Rectangle const *, bool bControlEvent) const = 0;
|
||||
|
||||
/// Debugging
|
||||
virtual OString dumpNotifyState() const = 0;
|
||||
};
|
||||
|
||||
@@ -1325,7 +1325,8 @@ public:
|
||||
const OUString& rAction,
|
||||
const std::vector<vcl::LOKPayloadItem>& rPayload = std::vector<vcl::LOKPayloadItem>()) const override;
|
||||
virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) const override;
|
||||
virtual void notifyInvalidation(tools::Rectangle const *) const override;
|
||||
virtual void notifyInvalidation(tools::Rectangle const* pRect) const override;
|
||||
virtual void notifyCursorInvalidation(tools::Rectangle const* pRect, bool bControlEvent) const override;
|
||||
virtual OString dumpNotifyState() const override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -768,6 +768,8 @@ public:
|
||||
void SetType( WindowType eType );
|
||||
WindowType GetType() const;
|
||||
std::string_view GetTypeName() const;
|
||||
bool IsFormControl() const;
|
||||
void SetFormControl(bool bFormControl);
|
||||
bool IsSystemWindow() const;
|
||||
SAL_DLLPRIVATE bool IsDockingWindow() const;
|
||||
bool IsDialog() const;
|
||||
|
||||
@@ -679,6 +679,16 @@ void SfxLokHelper::notifyWindow(const SfxViewShell* pThisView,
|
||||
pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_WINDOW, s);
|
||||
}
|
||||
|
||||
void SfxLokHelper::notifyCursorInvalidation(SfxViewShell const* pThisView, tools::Rectangle const* pRect, bool bControlEvent)
|
||||
{
|
||||
int nViewId = SfxLokHelper::getView(*pThisView);
|
||||
OString sPayload = OString::Concat("{ \"viewId\": \"") + OString::number(nViewId) + "\", \"rectangle\": \"" + pRect->toString();
|
||||
if (bControlEvent)
|
||||
sPayload += "\", \"controlEvent\": true";
|
||||
sPayload += " }";
|
||||
pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, sPayload);
|
||||
}
|
||||
|
||||
void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, tools::Rectangle const* pRect)
|
||||
{
|
||||
// -1 means all parts
|
||||
|
||||
@@ -3565,6 +3565,11 @@ void SfxViewShell::notifyInvalidation(tools::Rectangle const* pRect) const
|
||||
SfxLokHelper::notifyInvalidation(this, pRect);
|
||||
}
|
||||
|
||||
void SfxViewShell::notifyCursorInvalidation(tools::Rectangle const* pRect, bool bControlEvent) const
|
||||
{
|
||||
SfxLokHelper::notifyCursorInvalidation(this, pRect, bControlEvent);
|
||||
}
|
||||
|
||||
void SfxViewShell::NotifyOtherViews(int nType, const OString& rKey, const OString& rPayload)
|
||||
{
|
||||
SfxLokHelper::notifyOtherViews(this, nType, rKey, rPayload);
|
||||
|
||||
@@ -393,6 +393,7 @@ public:
|
||||
mbSecondary:1,
|
||||
mbNonHomogeneous:1,
|
||||
mbDoubleBufferingRequested:1;
|
||||
bool mbIsFormControl : 1 = false;
|
||||
|
||||
rtl::Reference< DNDListenerContainer > mxDNDListenerContainer;
|
||||
|
||||
|
||||
@@ -341,6 +341,10 @@ void Application::notifyInvalidation(tools::Rectangle const* /*pRect*/) const
|
||||
{
|
||||
}
|
||||
|
||||
void Application::notifyCursorInvalidation(tools::Rectangle const* /*pRect*/, bool /*bControlEvent*/) const
|
||||
{
|
||||
}
|
||||
|
||||
void Application::Execute()
|
||||
{
|
||||
ImplSVData* pSVData = ImplGetSVData();
|
||||
|
||||
@@ -241,7 +241,38 @@ void vcl::Cursor::ImplDoShow( bool bDrawDirect, bool bRestore )
|
||||
}
|
||||
}
|
||||
|
||||
void vcl::Cursor::LOKNotify( vcl::Window* pWindow, const OUString& rAction )
|
||||
namespace
|
||||
{
|
||||
|
||||
tools::Rectangle calcualteCursorRect(Point const& rPosition, Size const rSize, vcl::Window* pWindow, vcl::Window* pParent)
|
||||
{
|
||||
Point aPositionPixel = pWindow->LogicToPixel(rPosition);
|
||||
const tools::Long nX = pWindow->GetOutOffXPixel() + aPositionPixel.X() - pParent->GetOutOffXPixel();
|
||||
const tools::Long nY = pWindow->GetOutOffYPixel() + aPositionPixel.Y() - pParent->GetOutOffYPixel();
|
||||
|
||||
Size aSizePixel = pWindow->LogicToPixel(rSize);
|
||||
if (!aSizePixel.Width())
|
||||
aSizePixel.setWidth( pWindow->GetSettings().GetStyleSettings().GetCursorSize() );
|
||||
|
||||
Point aPosition(nX, nY);
|
||||
|
||||
if (pWindow->IsRTLEnabled() && pWindow->GetOutDev() && pParent->GetOutDev()
|
||||
&& !pWindow->GetOutDev()->ImplIsAntiparallel())
|
||||
pParent->GetOutDev()->ReMirror(aPosition);
|
||||
|
||||
if (!pWindow->IsRTLEnabled() && pWindow->GetOutDev() && pParent->GetOutDev()
|
||||
&& pWindow->GetOutDev()->ImplIsAntiparallel())
|
||||
{
|
||||
pWindow->GetOutDev()->ReMirror(aPosition);
|
||||
pParent->GetOutDev()->ReMirror(aPosition);
|
||||
}
|
||||
|
||||
return tools::Rectangle(aPosition, aSizePixel);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
void vcl::Cursor::LOKNotify(vcl::Window* pWindow, const OUString& rAction)
|
||||
{
|
||||
VclPtr<vcl::Window> pParent = pWindow->GetParentWithLOKNotifier();
|
||||
if (!pParent)
|
||||
@@ -251,39 +282,40 @@ void vcl::Cursor::LOKNotify( vcl::Window* pWindow, const OUString& rAction )
|
||||
assert(mpData && "Require ImplCursorData");
|
||||
assert(comphelper::LibreOfficeKit::isActive());
|
||||
|
||||
if (comphelper::LibreOfficeKit::isDialogPainting())
|
||||
return;
|
||||
|
||||
const vcl::ILibreOfficeKitNotifier* pNotifier = pParent->GetLOKNotifier();
|
||||
std::vector<vcl::LOKPayloadItem> aItems;
|
||||
if (rAction == "cursor_visible")
|
||||
aItems.emplace_back("visible", mpData->mbCurVisible ? "true" : "false");
|
||||
else if (rAction == "cursor_invalidate")
|
||||
|
||||
if (pWindow->IsFormControl() || (pWindow->GetParent() && pWindow->GetParent()->IsFormControl()))
|
||||
{
|
||||
const tools::Long nX = pWindow->GetOutOffXPixel() + pWindow->LogicToPixel(GetPos()).X() - pParent->GetOutOffXPixel();
|
||||
const tools::Long nY = pWindow->GetOutOffYPixel() + pWindow->LogicToPixel(GetPos()).Y() - pParent->GetOutOffYPixel();
|
||||
Size aSize = pWindow->LogicToPixel(GetSize());
|
||||
if (!aSize.Width())
|
||||
aSize.setWidth( pWindow->GetSettings().GetStyleSettings().GetCursorSize() );
|
||||
|
||||
Point aPos(nX, nY);
|
||||
|
||||
if (pWindow->IsRTLEnabled() && pWindow->GetOutDev() && pParent->GetOutDev()
|
||||
&& !pWindow->GetOutDev()->ImplIsAntiparallel())
|
||||
pParent->GetOutDev()->ReMirror(aPos);
|
||||
|
||||
if (!pWindow->IsRTLEnabled() && pWindow->GetOutDev() && pParent->GetOutDev()
|
||||
&& pWindow->GetOutDev()->ImplIsAntiparallel())
|
||||
if (rAction == "cursor_invalidate")
|
||||
{
|
||||
pWindow->GetOutDev()->ReMirror(aPos);
|
||||
pParent->GetOutDev()->ReMirror(aPos);
|
||||
tools::Rectangle aRect;
|
||||
if (pWindow->IsFormControl())
|
||||
aRect = calcualteCursorRect(GetPos(), GetSize(), pWindow, pWindow->GetParent());
|
||||
else
|
||||
aRect = calcualteCursorRect(GetPos(), GetSize(), pWindow, pWindow->GetParent()->GetParent());
|
||||
|
||||
OutputDevice* pDevice = mpData->mpWindow->GetOutDev();
|
||||
const tools::Rectangle aRectTwip = pDevice->PixelToLogic(aRect, MapMode(MapUnit::MapTwip));
|
||||
pNotifier->notifyCursorInvalidation(&aRectTwip, true);
|
||||
}
|
||||
|
||||
const tools::Rectangle aRect(aPos, aSize);
|
||||
aItems.emplace_back("rectangle", aRect.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (comphelper::LibreOfficeKit::isDialogPainting())
|
||||
return;
|
||||
|
||||
pNotifier->notifyWindow(pParent->GetLOKWindowId(), rAction, aItems);
|
||||
std::vector<vcl::LOKPayloadItem> aItems;
|
||||
if (rAction == "cursor_visible")
|
||||
{
|
||||
aItems.emplace_back("visible", mpData->mbCurVisible ? "true" : "false");
|
||||
}
|
||||
else if (rAction == "cursor_invalidate")
|
||||
{
|
||||
const tools::Rectangle aRect = calcualteCursorRect(GetPos(), GetSize(), pWindow, pParent);
|
||||
aItems.emplace_back("rectangle", aRect.toString());
|
||||
}
|
||||
pNotifier->notifyWindow(pParent->GetLOKWindowId(), rAction, aItems);
|
||||
}
|
||||
}
|
||||
|
||||
bool vcl::Cursor::ImplDoHide( bool bSuspend )
|
||||
|
||||
@@ -1045,6 +1045,17 @@ WindowType Window::GetType() const
|
||||
return WindowType::NONE;
|
||||
}
|
||||
|
||||
bool Window::IsFormControl() const
|
||||
{
|
||||
return mpWindowImpl ? mpWindowImpl->mbIsFormControl : false;
|
||||
}
|
||||
|
||||
void Window::SetFormControl(bool bFormControl)
|
||||
{
|
||||
if (mpWindowImpl)
|
||||
mpWindowImpl->mbIsFormControl = bFormControl;
|
||||
}
|
||||
|
||||
Dialog* Window::GetParentDialog() const
|
||||
{
|
||||
const vcl::Window *pWindow = this;
|
||||
|
||||
Reference in New Issue
Block a user