[Libreoffice-commits] core.git: 2 commits - vcl/unx

Caolán McNamara caolanm at redhat.com
Fri Jun 19 01:18:39 PDT 2015


 vcl/unx/generic/plugadapt/salplug.cxx |    8 -
 vcl/unx/gtk3/app/gtk3gtkinst.cxx      |  152 ++++++++++++++++++++++++++--------
 2 files changed, 120 insertions(+), 40 deletions(-)

New commits:
commit 031a347668e56c1b38c0539d30e9a1cbb808ca02
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jun 17 16:25:47 2015 +0100

    use gtk3 vclplug by default under GNOME3 if available
    
    Change-Id: I4efe8bdfb7080365094306aee9db6b69a7f9e86a

diff --git a/vcl/unx/generic/plugadapt/salplug.cxx b/vcl/unx/generic/plugadapt/salplug.cxx
index d49dccd..0d0b26d 100644
--- a/vcl/unx/generic/plugadapt/salplug.cxx
+++ b/vcl/unx/generic/plugadapt/salplug.cxx
@@ -68,14 +68,6 @@ static SalInstance* tryInstance( const OUString& rModuleBase, bool bForce = fals
         return svp_create_SalInstance();
 
     SalInstance* pInst = NULL;
-    // Disable gtk3 plugin for now unless explicitly requested via
-    // SAL_USE_VCLPLUGIN=gtk3 (would ideally depend on experimental mode, but
-    // reading the experimental mode setting requires the UNO service manager
-    // which has not yet been instantiated):
-    if (!bForce && rModuleBase == "gtk3")
-    {
-        return NULL;
-    }
     OUString aModule(
 #ifdef SAL_DLLPREFIX
             SAL_DLLPREFIX
commit 4008b6f9bfd919a7435047bc0aedcf7613009809
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Jun 19 09:16:40 2015 +0100

    gtk3: use owner-changed to detect losing/gaining clipboard ownership
    
    and use the generic implementation (for now at least) for the PRIMARY
    selection and use this for the CLIPBOARD selection
    
    Change-Id: I31d65534481dc73f0cf65d68a663b7dfbb13aa31

diff --git a/vcl/unx/gtk3/app/gtk3gtkinst.cxx b/vcl/unx/gtk3/app/gtk3gtkinst.cxx
index 6a67255..a45a5e1 100644
--- a/vcl/unx/gtk3/app/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/app/gtk3gtkinst.cxx
@@ -23,6 +23,7 @@
 #include "com/sun/star/datatransfer/dnd/XDragSource.hpp"
 #include "com/sun/star/datatransfer/dnd/XDropTarget.hpp"
 #include "com/sun/star/datatransfer/dnd/DNDConstants.hpp"
+#include <comphelper/processfactory.hxx>
 #include <comphelper/sequence.hxx>
 #include "cppuhelper/compbase.hxx"
 #include "cppuhelper/implbase1.hxx"
@@ -219,12 +220,51 @@ public:
     }
 };
 
+//We want to use gtk_clipboard_get_owner own owner-change to distinguish between
+//us gaining the clipboard ownership vs losing it. To do that we need to use
+//gtk_clipboard_set_with_owner and to do that we need a GObject, so define
+//one here for that purpose and just give it a VclGtkClipboard* member
+class VclGtkClipboard;
+
+typedef struct _ClipboardOwner ClipboardOwner;
+typedef struct _ClipboardOwnerClass ClipboardOwnerClass;
+
+struct _ClipboardOwner
+{
+    GObject parent_instance;
+
+    /* instance members */
+    VclGtkClipboard* m_pThis;
+};
+
+struct _ClipboardOwnerClass
+{
+  GObjectClass parent_class;
+
+  /* class members */
+};
+
+#define CLIPBOARD_OWNER_OBJECT           (clipboard_owner_get_type ())
+#define CLIPBOARD_OWNER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLIPBOARD_OWNER_OBJECT, ClipboardOwner))
+
+G_DEFINE_TYPE(ClipboardOwner, clipboard_owner, G_TYPE_OBJECT);
+
+static void clipboard_owner_class_init (ClipboardOwnerClass *)
+{
+}
+
+static void clipboard_owner_init(ClipboardOwner *)
+{
+}
+
 class VclGtkClipboard :
         public cppu::WeakComponentImplHelper<
         datatransfer::clipboard::XSystemClipboard,
         XServiceInfo>
 {
     osl::Mutex                                               m_aMutex;
+    ClipboardOwner*                                          m_pOwner;
+    gulong                                                   m_nOwnerChangedSignalId;
     Reference<css::datatransfer::XTransferable>              m_aContents;
     Reference<css::datatransfer::clipboard::XClipboardOwner> m_aOwner;
     std::list< Reference<css::datatransfer::clipboard::XClipboardListener> > m_aListeners;
@@ -233,16 +273,8 @@ class VclGtkClipboard :
 
 public:
 
-    VclGtkClipboard() : cppu::WeakComponentImplHelper<
-        datatransfer::clipboard::XSystemClipboard,
-        XServiceInfo
-        >( m_aMutex )
-    {
-    }
-
-    virtual ~VclGtkClipboard()
-    {
-    }
+    VclGtkClipboard();
+    virtual ~VclGtkClipboard();
 
     /*
      * XServiceInfo
@@ -290,6 +322,7 @@ public:
 
     void ClipboardGet(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info);
     void ClipboardClear(GtkClipboard *clipboard);
+    void OwnerChanged(GtkClipboard *clipboard, GdkEvent *event);
 private:
     GtkTargetEntry makeGtkTargetEntry(const css::datatransfer::DataFlavor& rFlavor);
 };
@@ -323,27 +356,11 @@ sal_Bool VclGtkClipboard::supportsService( const OUString& ServiceName ) throw(
 
 Reference< css::datatransfer::XTransferable > VclGtkClipboard::getContents() throw( RuntimeException, std::exception )
 {
-    if (! m_aContents.is())
-        m_aContents = new GtkTransferable();
-
-    return m_aContents;
-}
-
-namespace
-{
-    void ClipboardGetFunc(GtkClipboard *clipboard, GtkSelectionData *selection_data,
-                          guint info,
-                          gpointer user_data_or_owner)
-    {
-        VclGtkClipboard* pThis = static_cast<VclGtkClipboard*>(user_data_or_owner);
-        pThis->ClipboardGet(clipboard, selection_data, info);
-    }
-
-    void ClipboardClearFunc(GtkClipboard *clipboard, gpointer user_data_or_owner)
+    if (!m_aContents.is())
     {
-        VclGtkClipboard* pThis = static_cast<VclGtkClipboard*>(user_data_or_owner);
-        pThis->ClipboardClear(clipboard);
+        m_aContents = new GtkTransferable();
     }
+    return m_aContents;
 }
 
 void VclGtkClipboard::ClipboardGet(GtkClipboard* /*clipboard*/, GtkSelectionData *selection_data,
@@ -405,6 +422,17 @@ void VclGtkClipboard::ClipboardGet(GtkClipboard* /*clipboard*/, GtkSelectionData
                            aData.getLength());
 }
 
+void VclGtkClipboard::OwnerChanged(GtkClipboard* clipboard, GdkEvent* /*event*/)
+{
+    if (G_OBJECT(m_pOwner) != gtk_clipboard_get_owner(clipboard))
+    {
+        //null out m_aContents to return control to the system-one which
+        //will be retrieved if getContents is called again
+        setContents(Reference<css::datatransfer::XTransferable>(),
+                    Reference<css::datatransfer::clipboard::XClipboardOwner>());
+    }
+}
+
 void VclGtkClipboard::ClipboardClear(GtkClipboard * /*clipboard*/)
 {
     for (auto &a : m_aGtkTargets)
@@ -430,6 +458,47 @@ GtkTargetEntry VclGtkClipboard::makeGtkTargetEntry(const css::datatransfer::Data
     return aEntry;
 }
 
+namespace
+{
+    void ClipboardGetFunc(GtkClipboard *clipboard, GtkSelectionData *selection_data,
+                          guint info,
+                          gpointer user_data_or_owner)
+    {
+        VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis;
+        pThis->ClipboardGet(clipboard, selection_data, info);
+    }
+
+    void ClipboardClearFunc(GtkClipboard *clipboard, gpointer user_data_or_owner)
+    {
+        VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis;
+        pThis->ClipboardClear(clipboard);
+    }
+
+    void handle_owner_change(GtkClipboard *clipboard, GdkEvent *event, gpointer user_data)
+    {
+        VclGtkClipboard* pThis = static_cast<VclGtkClipboard*>(user_data);
+        pThis->OwnerChanged(clipboard, event);
+    }
+}
+
+VclGtkClipboard::VclGtkClipboard()
+    : cppu::WeakComponentImplHelper<datatransfer::clipboard::XSystemClipboard, XServiceInfo>
+        (m_aMutex)
+{
+    GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+    m_nOwnerChangedSignalId = g_signal_connect(clipboard, "owner-change",
+                                               G_CALLBACK(handle_owner_change), this);
+    m_pOwner = CLIPBOARD_OWNER(g_object_new(CLIPBOARD_OWNER_OBJECT, NULL));
+    m_pOwner->m_pThis = this;
+}
+
+VclGtkClipboard::~VclGtkClipboard()
+{
+    GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+    g_signal_handler_disconnect(clipboard, m_nOwnerChangedSignalId);
+    g_object_unref(m_pOwner);
+}
+
 void VclGtkClipboard::setContents(
         const Reference< css::datatransfer::XTransferable >& xTrans,
         const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner )
@@ -486,8 +555,10 @@ void VclGtkClipboard::setContents(
         //if there was a previous gtk_clipboard_set_with_data call then
         //ClipboardClearFunc will be called now
         GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
-        gtk_clipboard_set_with_data(clipboard, aGtkTargets.data(), aGtkTargets.size(),
-                                    ClipboardGetFunc, ClipboardClearFunc, this);
+        //use with_owner with m_pOwner so we can distinguish in handle_owner_change
+        //if we have gained or lost ownership of the clipboard
+        gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(),
+                                    ClipboardGetFunc, ClipboardClearFunc, G_OBJECT(m_pOwner));
         m_aGtkTargets = aGtkTargets;
     }
 
@@ -528,8 +599,25 @@ void VclGtkClipboard::removeClipboardListener( const Reference< datatransfer::cl
     m_aListeners.remove( listener );
 }
 
-Reference< XInterface > GtkInstance::CreateClipboard( const Sequence< Any >& )
+Reference< XInterface > GtkInstance::CreateClipboard(const Sequence< Any >& arguments)
 {
+    OUString sel;
+    if (arguments.getLength() == 0) {
+        sel = "CLIPBOARD";
+    } else if (arguments.getLength() != 1 || !(arguments[0] >>= sel)) {
+        throw css::lang::IllegalArgumentException(
+            "bad GtkInstance::CreateClipboard arguments",
+            css::uno::Reference<css::uno::XInterface>(), -1);
+    }
+
+    //see window.cxx HAVE_FEATURE_X11 hack, for now just support the
+    //system clipboard and not the primary selection
+    if (sel != "CLIPBOARD")
+    {
+        Reference< XComponentContext > xContext(comphelper::getProcessComponentContext());
+        return xContext->getServiceManager()->createInstanceWithContext("com.sun.star.datatransfer.clipboard.GenericClipboard", xContext);
+    }
+
     return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new VclGtkClipboard()) );
 }
 


More information about the Libreoffice-commits mailing list