ICCCM says that the TIMESTAMP atom is required, so provide it. This is patch 1424755 from Timothée Lecomte.

Additionally fix a memory leak from a gdk_atom_name.
(Forward port from 2.6 branch to both HEAD gtk sources)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38086 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Mart Raudsepp
2006-03-15 03:01:06 +00:00
parent cc6e44bf0b
commit d394f0c93f
2 changed files with 69 additions and 10 deletions

View File

@@ -35,6 +35,7 @@
GdkAtom g_clipboardAtom = 0; GdkAtom g_clipboardAtom = 0;
GdkAtom g_targetsAtom = 0; GdkAtom g_targetsAtom = 0;
GdkAtom g_timestampAtom = 0;
#if defined(__WXGTK20__) && wxUSE_UNICODE #if defined(__WXGTK20__) && wxUSE_UNICODE
extern GdkAtom g_altTextAtom; extern GdkAtom g_altTextAtom;
@@ -87,14 +88,17 @@ targets_selection_received( GtkWidget *WXUNUSED(widget),
GdkAtom type = selection_data->type; GdkAtom type = selection_data->type;
if ( type != GDK_SELECTION_TYPE_ATOM ) 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, wxLogTrace( TRACE_CLIPBOARD,
_T("got unsupported clipboard target") ); _T("got unsupported clipboard target") );
clipboard->m_waiting = FALSE; clipboard->m_waiting = FALSE;
g_free(atom_name);
return; return;
} }
g_free(atom_name);
} }
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
@@ -243,7 +247,7 @@ selection_handler( GtkWidget *WXUNUSED(widget),
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint WXUNUSED(info), guint WXUNUSED(info),
guint WXUNUSED(time), guint WXUNUSED(time),
gpointer WXUNUSED(data) ) gpointer signal_data )
{ {
if (!wxTheClipboard) return; if (!wxTheClipboard) return;
@@ -251,15 +255,34 @@ selection_handler( GtkWidget *WXUNUSED(widget),
wxDataObject *data = wxTheClipboard->m_data; 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 ); wxDataFormat format( selection_data->target );
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
wxLogTrace(TRACE_CLIPBOARD, 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(), format.GetId().c_str(),
wxString::FromAscii(gdk_atom_name(selection_data->target)).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->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 #endif
@@ -336,6 +359,7 @@ wxClipboard::wxClipboard()
if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE ); if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", 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_formatSupported = FALSE;
m_targetRequested = 0; m_targetRequested = 0;
@@ -435,6 +459,11 @@ bool wxClipboard::AddData( wxDataObject *data )
GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
: g_clipboardAtom; : 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++) for (size_t i = 0; i < m_data->GetFormatCount(); i++)
{ {
@@ -454,7 +483,8 @@ bool wxClipboard::AddData( wxDataObject *data )
delete[] array; delete[] array;
g_signal_connect (m_clipboardWidget, "selection_get", 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 #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */

View File

@@ -35,6 +35,7 @@
GdkAtom g_clipboardAtom = 0; GdkAtom g_clipboardAtom = 0;
GdkAtom g_targetsAtom = 0; GdkAtom g_targetsAtom = 0;
GdkAtom g_timestampAtom = 0;
// the trace mask we use with wxLogTrace() - call // the trace mask we use with wxLogTrace() - call
// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here // 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; GdkAtom type = selection_data->type;
if ( type != GDK_SELECTION_TYPE_ATOM ) 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, wxLogTrace( TRACE_CLIPBOARD,
_T("got unsupported clipboard target") ); _T("got unsupported clipboard target") );
clipboard->m_waiting = FALSE; clipboard->m_waiting = FALSE;
g_free(atom_name);
return; return;
} }
g_free(atom_name);
} }
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
@@ -239,7 +243,7 @@ selection_handler( GtkWidget *WXUNUSED(widget),
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint WXUNUSED(info), guint WXUNUSED(info),
guint WXUNUSED(time), guint WXUNUSED(time),
gpointer WXUNUSED(data) ) gpointer signal_data )
{ {
if (!wxTheClipboard) return; if (!wxTheClipboard) return;
@@ -247,15 +251,34 @@ selection_handler( GtkWidget *WXUNUSED(widget),
wxDataObject *data = wxTheClipboard->m_data; 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 ); wxDataFormat format( selection_data->target );
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
wxLogTrace(TRACE_CLIPBOARD, 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(), format.GetId().c_str(),
wxString::FromAscii(gdk_atom_name(selection_data->target)).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->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 #endif
@@ -325,6 +348,7 @@ wxClipboard::wxClipboard()
if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE ); if (!g_clipboardAtom) g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE );
if (!g_targetsAtom) g_targetsAtom = gdk_atom_intern ("TARGETS", 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_formatSupported = FALSE;
m_targetRequested = 0; m_targetRequested = 0;
@@ -424,6 +448,11 @@ bool wxClipboard::AddData( wxDataObject *data )
GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY GdkAtom clipboard = m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY
: g_clipboardAtom; : 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++) 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), gtk_signal_connect( GTK_OBJECT(m_clipboardWidget),
"selection_get", "selection_get",
GTK_SIGNAL_FUNC(selection_handler), GTK_SIGNAL_FUNC(selection_handler),
(gpointer) NULL ); GUINT_TO_POINTER( gtk_get_current_event_time() ) );
#if wxUSE_THREADS #if wxUSE_THREADS
/* disable GUI threads */ /* disable GUI threads */