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:
@@ -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 */
|
||||||
|
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user