vcl/inc/ClipboardSelectionType.hxx | 18 ++++++++++++++++++ vcl/inc/osx/salinst.h | 2 +- vcl/inc/qt5/QtInstance.hxx | 4 ++-- vcl/inc/qt5/QtTools.hxx | 5 +++++ vcl/inc/salinst.hxx | 3 ++- vcl/inc/unx/gtk/gtkinst.hxx | 8 +------- vcl/inc/unx/salinst.h | 2 +- vcl/osx/service_entry.cxx | 4 ++-- vcl/qt5/QtInstance.cxx | 30 ++++++++---------------------- vcl/qt5/QtTools.cxx | 14 ++++++++++++++ vcl/source/components/dtranscomp.cxx | 24 ++++++++++++++++++++---- vcl/unx/generic/dtrans/X11_service.cxx | 13 +++---------- vcl/unx/gtk3/gtkinst.cxx | 16 ++-------------- vcl/win/dtrans/WinClipboard.cxx | 5 +++-- 14 files changed, 82 insertions(+), 66 deletions(-)
New commits: commit f8c0774211f181acda7f4af373ab6c8f2c909901 Author: Michael Weghorn <[email protected]> AuthorDate: Fri Feb 27 14:30:47 2026 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Sat Feb 28 09:20:25 2026 +0100 vcl: Centralize evaluating Sequence<Any> args for clipboard creation vcl_SystemClipboard_get_implementation is used to create an instance of the system clipboard. It calls the platform/VCL plugin specific SalInstance::CreateCreateClipboard implementations. So far, vcl_SystemClipboard_get_implementation was passing its Sequence<Any> args as is to the SalInstance::CreateCreateClipboard implementations, which would then evaluate what kind of clipboard to create (whether for primary selection or the clipboard). In particular the Linux backends were implementing the same logic. Unify and deduplicate this a bit and use stronger typing for SalInstance::CreateCreateClipboard by evaluating the args in vcl_SystemClipboard_get_implementation and changing the SalInstance::CreateCreateClipboard signature to take an enum param that indicates what type of clipboard to create. Move the existing ClipboardSelectionType enum class so far only used in the gtk VCL plugins to a new header and take over the logic to evaluate the args to determine the type to use from there as well. (Similar logic was duplicated elsewhere, too). The SalInstance::CreateClipboard base class implementation didn't support any params. The previous case of not passing params is now replaced by explicitly passing ClipboardSelectionType::Clipboard, so do (and expect) that instead. Given that SalInstance is the WinSalInstance base class and WinSalInstance doesn't override SalInstance::CreateCreateClipboard, that implementation also gets used in dtrans_CWinClipboard_get_implementation when running unit tests for the ImplGetSVData()->mpDefInst->CreateClipboard(...) case. X11SalInstance::CreateClipboard could previously in theory support any random string for the X11 clipboard name, but is now restricted to "CLIPBOARD" and "PRIMARY" as well. Change-Id: If913d7514fe7d5bcea34430928ec2ec3d98774b6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200631 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/vcl/inc/ClipboardSelectionType.hxx b/vcl/inc/ClipboardSelectionType.hxx new file mode 100644 index 000000000000..90b4e1206633 --- /dev/null +++ b/vcl/inc/ClipboardSelectionType.hxx @@ -0,0 +1,18 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +enum class ClipboardSelectionType +{ + Clipboard = 0, + Primary = 1 +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/inc/osx/salinst.h b/vcl/inc/osx/salinst.h index f6ef23541004..40716200fe53 100644 --- a/vcl/inc/osx/salinst.h +++ b/vcl/inc/osx/salinst.h @@ -138,7 +138,7 @@ public: // dtrans implementation virtual css::uno::Reference<css::datatransfer::clipboard::XClipboard> - CreateClipboard(const css::uno::Sequence<css::uno::Any>& i_rArguments) override; + CreateClipboard(ClipboardSelectionType eSelection) override; virtual css::uno::Reference<css::datatransfer::dnd::XDragSource> ImplCreateDragSource(const SystemEnvData& rSysEnv) override; virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx index a49e7b44c8fd..843556d64073 100644 --- a/vcl/inc/qt5/QtInstance.hxx +++ b/vcl/inc/qt5/QtInstance.hxx @@ -75,7 +75,7 @@ class VCLPLUG_QT_PUBLIC QtInstance : public QObject, const bool m_bUseCairo; QtTimer* m_pTimer; bool m_bSleeping; - std::unordered_map<OUString, rtl::Reference<QtClipboard>> m_aClipboards; + std::unordered_map<ClipboardSelectionType, rtl::Reference<QtClipboard>> m_aClipboards; std::unique_ptr<QApplication> m_pQApplication; std::vector<FreeableCStr> m_pFakeArgvFreeable; @@ -221,7 +221,7 @@ public: createFolderPicker(const css::uno::Reference<css::uno::XComponentContext>&) override; virtual css::uno::Reference<css::datatransfer::clipboard::XClipboard> - CreateClipboard(const css::uno::Sequence<css::uno::Any>& i_rArguments) override; + CreateClipboard(ClipboardSelectionType eSelection) override; virtual css::uno::Reference<css::datatransfer::dnd::XDragSource> ImplCreateDragSource(const SystemEnvData& rSysEnv) override; virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx index 064246a53645..5cb5174110f6 100644 --- a/vcl/inc/qt5/QtTools.hxx +++ b/vcl/inc/qt5/QtTools.hxx @@ -21,6 +21,9 @@ #include <config_vclplug.h> +#include <ClipboardSelectionType.hxx> + +#include <QtGui/QClipboard> #include <QtCore/QDate> #include <QtCore/QPoint> #include <QtCore/QRect> @@ -102,6 +105,8 @@ Qt::Alignment toQtAlignment(TxtAlign eAlign); Qt::CheckState toQtCheckState(TriState eTristate); TriState toVclTriState(Qt::CheckState eTristate); +QClipboard::Mode toQClipboardMode(ClipboardSelectionType eSelection); + Qt::DropActions toQtDropActions(sal_Int8 dragOperation); sal_Int8 toVclDropActions(Qt::DropActions dragOperation); sal_Int8 toVclDropAction(Qt::DropAction dragOperation); diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx index ad77d8d5a8ab..01fe719f77dd 100644 --- a/vcl/inc/salinst.hxx +++ b/vcl/inc/salinst.hxx @@ -29,6 +29,7 @@ #include <vcl/weld/ColorChooserDialog.hxx> #include <vcl/weld/weld.hxx> +#include "ClipboardSelectionType.hxx" #include "displayconnectiondispatch.hxx" #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> @@ -201,7 +202,7 @@ public: // dtrans implementation virtual css::uno::Reference<css::datatransfer::clipboard::XClipboard> - CreateClipboard(const css::uno::Sequence<css::uno::Any>& i_rArguments); + CreateClipboard(ClipboardSelectionType eSelection); virtual css::uno::Reference<css::datatransfer::dnd::XDragSource> ImplCreateDragSource(const SystemEnvData& rSysEnv); virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx index d09675f2b553..25fbaf8c9e6e 100644 --- a/vcl/inc/unx/gtk/gtkinst.hxx +++ b/vcl/inc/unx/gtk/gtkinst.hxx @@ -225,12 +225,6 @@ public: css::uno::Reference<css::datatransfer::XTransferable> const & GetTransferable() const { return m_xTrans; } }; -enum class ClipboardSelectionType -{ - Clipboard = 0, - Primary = 1 -}; - class GtkSalTimer; class GtkInstance final : public SvpSalInstance { @@ -277,7 +271,7 @@ public: createFolderPicker( const css::uno::Reference< css::uno::XComponentContext >& ) override; virtual css::uno::Reference<css::datatransfer::clipboard::XClipboard> - CreateClipboard(const css::uno::Sequence<css::uno::Any>& i_rArguments) override; + CreateClipboard(ClipboardSelectionType eSelection) override; virtual css::uno::Reference<css::datatransfer::dnd::XDragSource> ImplCreateDragSource(const SystemEnvData& rSysEnv) override; virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> diff --git a/vcl/inc/unx/salinst.h b/vcl/inc/unx/salinst.h index 71bfec19b79e..22b4d6422450 100644 --- a/vcl/inc/unx/salinst.h +++ b/vcl/inc/unx/salinst.h @@ -82,7 +82,7 @@ public: // dtrans implementation virtual css::uno::Reference<css::datatransfer::clipboard::XClipboard> - CreateClipboard(const css::uno::Sequence<css::uno::Any>& i_rArguments) override; + CreateClipboard(ClipboardSelectionType eSelection) override; virtual css::uno::Reference<css::datatransfer::dnd::XDragSource> ImplCreateDragSource(const SystemEnvData& rSysEnv) override; virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> diff --git a/vcl/osx/service_entry.cxx b/vcl/osx/service_entry.cxx index 5829a07ef75f..1c4d5ea44675 100644 --- a/vcl/osx/service_entry.cxx +++ b/vcl/osx/service_entry.cxx @@ -39,10 +39,10 @@ using namespace ::com::sun::star::lang; using namespace ::com::sun::star::datatransfer::clipboard; uno::Reference<css::datatransfer::clipboard::XClipboard> -AquaSalInstance::CreateClipboard(const Sequence<Any>& i_rArguments) +AquaSalInstance::CreateClipboard(ClipboardSelectionType eSelection) { if ( Application::IsHeadlessModeEnabled() || o3tl::IsRunningUnitTest() || o3tl::IsRunningUITest() ) - return SalInstance::CreateClipboard( i_rArguments ); + return SalInstance::CreateClipboard(eSelection); SalData* pSalData = GetSalData(); if( ! pSalData->mxClipboard.is() ) diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx index 62446e9cc21b..82a46a256227 100644 --- a/vcl/qt5/QtInstance.cxx +++ b/vcl/qt5/QtInstance.cxx @@ -646,42 +646,28 @@ QtInstance::createFolderPicker(const css::uno::Reference<css::uno::XComponentCon } css::uno::Reference<css::datatransfer::clipboard::XClipboard> -QtInstance::CreateClipboard(const css::uno::Sequence<css::uno::Any>& arguments) +QtInstance::CreateClipboard(ClipboardSelectionType eSelection) { - OUString sel; - if (arguments.getLength() == 0) - { - sel = "CLIPBOARD"; - } - else if (arguments.getLength() != 1 || !(arguments[0] >>= sel)) - { - throw css::lang::IllegalArgumentException(u"bad QtInstance::CreateClipboard arguments"_ustr, - css::uno::Reference<css::uno::XInterface>(), -1); - } - // This could also use RunInMain, but SolarMutexGuard is enough // since at this point we're not accessing the clipboard, just get the // accessor to the clipboard. SolarMutexGuard aGuard; - auto it = m_aClipboards.find(sel); + auto it = m_aClipboards.find(eSelection); if (it != m_aClipboards.end()) return it->second; - rtl::Reference<QtClipboard> pClipboard = EmscriptenLightweightRunInMainThread([&sel] { - static const std::map<OUString, QClipboard::Mode> aNameToClipboardMap - = { { "CLIPBOARD", QClipboard::Clipboard }, { "PRIMARY", QClipboard::Selection } }; - + rtl::Reference<QtClipboard> pClipboard = EmscriptenLightweightRunInMainThread([&eSelection] { assert(QApplication::clipboard()->thread() == qApp->thread()); - auto iter = aNameToClipboardMap.find(sel); - if (iter != aNameToClipboardMap.end() && QtClipboard::isSupported(iter->second)) - return rtl::Reference<QtClipboard>(new QtClipboard(iter->second)); - SAL_WARN("vcl.qt", "Ignoring unrecognized clipboard type: '" << sel << "'"); + const QClipboard::Mode eClipboardMode = toQClipboardMode(eSelection); + if (QtClipboard::isSupported(eClipboardMode)) + return rtl::Reference<QtClipboard>(new QtClipboard(eClipboardMode)); + SAL_WARN("vcl.qt", "Ignoring unsupported clipboard mode: '" << eClipboardMode << "'"); return rtl::Reference<QtClipboard>(); }); if (pClipboard.is()) - m_aClipboards[sel] = pClipboard; + m_aClipboards[eSelection] = pClipboard; return pClipboard; } diff --git a/vcl/qt5/QtTools.cxx b/vcl/qt5/QtTools.cxx index cda318dc0332..ab317a0c4cca 100644 --- a/vcl/qt5/QtTools.cxx +++ b/vcl/qt5/QtTools.cxx @@ -74,6 +74,20 @@ Qt::CheckState toQtCheckState(TriState eTristate) } }; +QClipboard::Mode toQClipboardMode(ClipboardSelectionType eSelection) +{ + switch (eSelection) + { + case ClipboardSelectionType::Clipboard: + return QClipboard::Mode::Clipboard; + case ClipboardSelectionType::Primary: + return QClipboard::Mode::Selection; + default: + assert(false && "unhandled ClipboardSelectionType value"); + return QClipboard::Mode::Clipboard; + } +} + TriState toVclTriState(Qt::CheckState eTristate) { switch (eTristate) diff --git a/vcl/source/components/dtranscomp.cxx b/vcl/source/components/dtranscomp.cxx index 850d06a89533..f93e55d70eb9 100644 --- a/vcl/source/components/dtranscomp.cxx +++ b/vcl/source/components/dtranscomp.cxx @@ -26,6 +26,7 @@ #include <tools/debug.hxx> #include <vcl/svapp.hxx> +#include <ClipboardSelectionType.hxx> #include <svdata.hxx> #include <salinst.hxx> @@ -191,7 +192,22 @@ vcl_SystemClipboard_get_implementation( css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const& args) { SolarMutexGuard aGuard; - auto xClipboard = GetSalInstance()->CreateClipboard( args ); + + ClipboardSelectionType eSelection = ClipboardSelectionType::Clipboard; + if (args.hasElements()) + { + OUString sSel; + if (args.getLength() != 1 || !(args[0] >>= sSel)) + { + throw css::lang::IllegalArgumentException( + u"Invalid arguments to create clipboard"_ustr, + css::uno::Reference<css::uno::XInterface>(), -1); + } + eSelection = (sSel == u"CLIPBOARD") ? ClipboardSelectionType::Clipboard + : ClipboardSelectionType::Primary; + } + + auto xClipboard = GetSalInstance()->CreateClipboard(eSelection); if (xClipboard.is()) xClipboard->acquire(); return xClipboard.get(); @@ -352,11 +368,11 @@ void GenericDropTarget::setDefaultActions( sal_Int8) * SalInstance generic */ Reference<css::datatransfer::clipboard::XClipboard> -SalInstance::CreateClipboard(const Sequence<Any>& arguments) +SalInstance::CreateClipboard(ClipboardSelectionType eSelection) { - if (arguments.hasElements()) { + if (eSelection != ClipboardSelectionType::Clipboard) { throw css::lang::IllegalArgumentException( - u"non-empty SalInstance::CreateClipboard arguments"_ustr, {}, -1); + u"unsupported SalInstance::CreateClipboard argument"_ustr, {}, -1); } #ifdef IOS return new vcl::GenericClipboard(); diff --git a/vcl/unx/generic/dtrans/X11_service.cxx b/vcl/unx/generic/dtrans/X11_service.cxx index 88528bfda900..2e0d0bb11984 100644 --- a/vcl/unx/generic/dtrans/X11_service.cxx +++ b/vcl/unx/generic/dtrans/X11_service.cxx @@ -50,22 +50,15 @@ Sequence< OUString > x11::Xdnd_dropTarget_getSupportedServiceNames() } css::uno::Reference<css::datatransfer::clipboard::XClipboard> -X11SalInstance::CreateClipboard(const Sequence<Any>& arguments) +X11SalInstance::CreateClipboard(ClipboardSelectionType eSelection) { if ( o3tl::IsRunningUnitTest() || o3tl::IsRunningUITest() ) - return SalInstance::CreateClipboard( arguments ); + return SalInstance::CreateClipboard(eSelection); SelectionManager& rManager = SelectionManager::get(); rManager.initialize(); - OUString sel; - if (!arguments.hasElements()) { - sel = "CLIPBOARD"; - } else if (arguments.getLength() != 1 || !(arguments[0] >>= sel)) { - throw css::lang::IllegalArgumentException( - u"bad X11SalInstance::CreateClipboard arguments"_ustr, - css::uno::Reference<css::uno::XInterface>(), -1); - } + const OUString sel = eSelection == ClipboardSelectionType::Clipboard ? u"CLIPBOARD"_ustr : u"PRIMARY"_ustr; Atom nSelection = rManager.getAtom(sel); std::unordered_map< Atom, css::uno::Reference< XClipboard > >::iterator it = m_aInstances.find( nSelection ); diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 9daa1c5a05fa..f0033194248f 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -1614,22 +1614,10 @@ void VclGtkClipboard::removeClipboardListener( const Reference< datatransfer::cl } Reference<css::datatransfer::clipboard::XClipboard> -GtkInstance::CreateClipboard(const Sequence<Any>& arguments) +GtkInstance::CreateClipboard(ClipboardSelectionType eSelection) { if ( o3tl::IsRunningUnitTest() || o3tl::IsRunningUITest() ) - return SalInstance::CreateClipboard( arguments ); - - OUString sel; - if (!arguments.hasElements()) { - sel = "CLIPBOARD"; - } else if (arguments.getLength() != 1 || !(arguments[0] >>= sel)) { - throw css::lang::IllegalArgumentException( - u"bad GtkInstance::CreateClipboard arguments"_ustr, - css::uno::Reference<css::uno::XInterface>(), -1); - } - - ClipboardSelectionType eSelection = (sel == "CLIPBOARD") ? ClipboardSelectionType::Clipboard - : ClipboardSelectionType::Primary; + return SalInstance::CreateClipboard(eSelection); auto aIt = m_aClipboards.find(eSelection); if (aIt != m_aClipboards.end()) diff --git a/vcl/win/dtrans/WinClipboard.cxx b/vcl/win/dtrans/WinClipboard.cxx index 335e3a7fa7f1..59b13c16e0cb 100644 --- a/vcl/win/dtrans/WinClipboard.cxx +++ b/vcl/win/dtrans/WinClipboard.cxx @@ -357,7 +357,7 @@ uno::Sequence<OUString> SAL_CALL CWinClipboard::getSupportedServiceNames() extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* dtrans_CWinClipboard_get_implementation(css::uno::XComponentContext* context, - css::uno::Sequence<css::uno::Any> const& args) + css::uno::Sequence<css::uno::Any> const&) { // We run unit tests in parallel, which is a problem when touching a shared resource // like the system clipboard, so rather use the dummy GenericClipboard. @@ -366,7 +366,8 @@ dtrans_CWinClipboard_get_implementation(css::uno::XComponentContext* context, if (bRunningUnitTest) { SolarMutexGuard aGuard; - auto xClipboard = ImplGetSVData()->mpDefInst->CreateClipboard(args); + auto xClipboard + = ImplGetSVData()->mpDefInst->CreateClipboard(ClipboardSelectionType::Clipboard); if (xClipboard.is()) xClipboard->acquire(); return xClipboard.get();
