From d394f0c93f547ceb1e9efe8b5e5c9edc7516becf Mon Sep 17 00:00:00 2001 From: Mart Raudsepp Date: Wed, 15 Mar 2006 03:01:06 +0000 Subject: [PATCH] =?utf8?q?ICCCM=20says=20that=20the=20TIMESTAMP=20atom=20i?= =?utf8?q?s=20required,=20so=20provide=20it.=20This=20is=20patch=201424755?= =?utf8?q?=20from=20Timoth=C3=A9e=20Lecomte.=20Additionally=20fix=20a=20me?= =?utf8?q?mory=20leak=20from=20a=20gdk=5Fatom=5Fname.=20(Forward=20port=20?= =?utf8?q?from=202.6=20branch=20to=20both=20HEAD=20gtk=20sources)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38086 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/clipbrd.cpp | 40 +++++++++++++++++++++++++++++++++++----- src/gtk1/clipbrd.cpp | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/gtk/clipbrd.cpp b/src/gtk/clipbrd.cpp index 432c2b4e93..35ddcd3d16 100644 --- a/src/gtk/clipbrd.cpp +++ b/src/gtk/clipbrd.cpp @@ -35,6 +35,7 @@ GdkAtom g_clipboardAtom = 0; GdkAtom g_targetsAtom = 0; +GdkAtom g_timestampAtom = 0; #if defined(__WXGTK20__) && wxUSE_UNICODE extern GdkAtom g_altTextAtom; @@ -87,14 +88,17 @@ targets_selection_received( GtkWidget *WXUNUSED(widget), GdkAtom type = selection_data->type; if ( type != GDK_SELECTION_TYPE_ATOM ) { - if ( strcmp(gdk_atom_name(type), "TARGETS") ) + gchar* atom_name = gdk_atom_name(type); + if ( strcmp(atom_name, "TARGETS") ) { wxLogTrace( TRACE_CLIPBOARD, _T("got unsupported clipboard target") ); clipboard->m_waiting = FALSE; + g_free(atom_name); return; } + g_free(atom_name); } #ifdef __WXDEBUG__ @@ -243,7 +247,7 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data, guint WXUNUSED(info), guint WXUNUSED(time), - gpointer WXUNUSED(data) ) + gpointer signal_data ) { if (!wxTheClipboard) return; @@ -251,15 +255,34 @@ selection_handler( GtkWidget *WXUNUSED(widget), wxDataObject *data = wxTheClipboard->m_data; + // ICCCM says that TIMESTAMP is a required atom. + // In particular, it satisfies Klipper, which polls + // TIMESTAMP to see if the clipboards content has changed. + // It shall return the time which was used to set the data. + if (selection_data->target == g_timestampAtom) + { + uint timestamp = GPOINTER_TO_UINT (signal_data); + gtk_selection_data_set(selection_data, + GDK_SELECTION_TYPE_INTEGER, + 32, + (guchar*)&(timestamp), + sizeof(timestamp)); + wxLogTrace(TRACE_CLIPBOARD, + _T("Clipboard TIMESTAMP requested, returning timestamp=%u"), + timestamp); + return; + } + wxDataFormat format( selection_data->target ); #ifdef __WXDEBUG__ wxLogTrace(TRACE_CLIPBOARD, - _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s"), + _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"), format.GetId().c_str(), wxString::FromAscii(gdk_atom_name(selection_data->target)).c_str(), wxString::FromAscii(gdk_atom_name(selection_data->type)).c_str(), - wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str() + wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str(), + GPOINTER_TO_UINT( signal_data ) ); #endif @@ -336,6 +359,7 @@ wxClipboard::wxClipboard() if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE ); if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE); + if (!g_timestampAtom) g_timestampAtom = gdk_atom_intern ("TIMESTAMP", FALSE); m_formatSupported = FALSE; m_targetRequested = 0; @@ -435,6 +459,11 @@ bool wxClipboard::AddData( wxDataObject *data ) GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY : g_clipboardAtom; + // by default provide TIMESTAMP as a target + gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget), + clipboard, + g_timestampAtom, + 0 ); for (size_t i = 0; i < m_data->GetFormatCount(); i++) { @@ -454,7 +483,8 @@ bool wxClipboard::AddData( wxDataObject *data ) delete[] array; g_signal_connect (m_clipboardWidget, "selection_get", - G_CALLBACK (selection_handler), NULL); + G_CALLBACK (selection_handler), + GUINT_TO_POINTER (gtk_get_current_event_time()) ); #if wxUSE_THREADS /* disable GUI threads */ diff --git a/src/gtk1/clipbrd.cpp b/src/gtk1/clipbrd.cpp index 8adca083d2..294e0fb3cb 100644 --- a/src/gtk1/clipbrd.cpp +++ b/src/gtk1/clipbrd.cpp @@ -35,6 +35,7 @@ GdkAtom g_clipboardAtom = 0; GdkAtom g_targetsAtom = 0; +GdkAtom g_timestampAtom = 0; // the trace mask we use with wxLogTrace() - call // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here @@ -83,14 +84,17 @@ targets_selection_received( GtkWidget *WXUNUSED(widget), GdkAtom type = selection_data->type; if ( type != GDK_SELECTION_TYPE_ATOM ) { - if ( strcmp(gdk_atom_name(type), "TARGETS") ) + gchar* atom_name = gdk_atom_name(type); + if ( strcmp(atom_name, "TARGETS") ) { wxLogTrace( TRACE_CLIPBOARD, _T("got unsupported clipboard target") ); clipboard->m_waiting = FALSE; + g_free(atom_name); return; } + g_free(atom_name); } #ifdef __WXDEBUG__ @@ -239,7 +243,7 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data, guint WXUNUSED(info), guint WXUNUSED(time), - gpointer WXUNUSED(data) ) + gpointer signal_data ) { if (!wxTheClipboard) return; @@ -247,15 +251,34 @@ selection_handler( GtkWidget *WXUNUSED(widget), wxDataObject *data = wxTheClipboard->m_data; + // ICCCM says that TIMESTAMP is a required atom. + // In particular, it satisfies Klipper, which polls + // TIMESTAMP to see if the clipboards content has changed. + // It shall return the time which was used to set the data. + if (selection_data->target == g_timestampAtom) + { + uint timestamp = GPOINTER_TO_UINT (signal_data); + gtk_selection_data_set(selection_data, + GDK_SELECTION_TYPE_INTEGER, + 32, + (guchar*)&(timestamp), + sizeof(timestamp)); + wxLogTrace(TRACE_CLIPBOARD, + _T("Clipboard TIMESTAMP requested, returning timestamp=%u"), + timestamp); + return; + } + wxDataFormat format( selection_data->target ); #ifdef __WXDEBUG__ wxLogTrace(TRACE_CLIPBOARD, - _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s"), + _T("clipboard data in format %s, GtkSelectionData is target=%s type=%s selection=%s timestamp=%u"), format.GetId().c_str(), wxString::FromAscii(gdk_atom_name(selection_data->target)).c_str(), wxString::FromAscii(gdk_atom_name(selection_data->type)).c_str(), - wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str() + wxString::FromAscii(gdk_atom_name(selection_data->selection)).c_str(), + GPOINTER_TO_UINT( signal_data ) ); #endif @@ -325,6 +348,7 @@ wxClipboard::wxClipboard() if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE ); if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE); + if (!g_timestampAtom) g_timestampAtom = gdk_atom_intern ("TIMESTAMP", FALSE); m_formatSupported = FALSE; m_targetRequested = 0; @@ -424,6 +448,11 @@ bool wxClipboard::AddData( wxDataObject *data ) GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY : g_clipboardAtom; + // by default provide TIMESTAMP as a target + gtk_selection_add_target( GTK_WIDGET(m_clipboardWidget), + clipboard, + g_timestampAtom, + 0 ); for (size_t i = 0; i < m_data->GetFormatCount(); i++) { @@ -445,7 +474,7 @@ bool wxClipboard::AddData( wxDataObject *data ) gtk_signal_connect( GTK_OBJECT(m_clipboardWidget), "selection_get", GTK_SIGNAL_FUNC(selection_handler), - (gpointer) NULL ); + GUINT_TO_POINTER( gtk_get_current_event_time() ) ); #if wxUSE_THREADS /* disable GUI threads */ -- 2.45.2