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();

Reply via email to