diff --git a/interface/wx/clipbrd.h b/interface/wx/clipbrd.h index d1d337123a..c8fb6fc277 100644 --- a/interface/wx/clipbrd.h +++ b/interface/wx/clipbrd.h @@ -53,6 +53,13 @@ } @endcode + @note On GTK, the clipboard behavior can vary depending on the configuration of + the end-user's machine. In order for the clipboard data to persist after + the window closes, a clipboard manager must be installed. Some clipboard + managers will automatically flush the clipboard after each new piece of + data is added, while others will not. The @Flush() function will force + the clipboard manager to flush the data. + @library{wxcore} @category{dnd} @@ -99,6 +106,10 @@ public: Currently this method is implemented in MSW and GTK and always returns @false otherwise. + @note On GTK, only the non-primary selection can be flushed. Calling this function + when the clipboard is using the primary selection will return @false and not + make any data available after the program exits. + @return @false if the operation is unsuccessful for any reason. */ virtual bool Flush(); diff --git a/samples/clipboard/clipboard.cpp b/samples/clipboard/clipboard.cpp index 1b3e068183..9d608e43de 100644 --- a/samples/clipboard/clipboard.cpp +++ b/samples/clipboard/clipboard.cpp @@ -151,7 +151,8 @@ void MyFrame::OnFlush(wxCommandEvent &WXUNUSED(event)) return; } - if ( !wxTheClipboard->AddData(new wxTextDataObject("Text from wx clipboard sample")) ) + wxString clipData = wxString::Format("Text from wx clipboard sample at %s" , wxDateTime::Now().Format()); + if ( !wxTheClipboard->AddData(new wxTextDataObject(clipData)) ) { m_textctrl->AppendText("Failed to put text on clipboard.\n"); return; diff --git a/src/gtk/clipbrd.cpp b/src/gtk/clipbrd.cpp index 6d6aad79f6..ca86c9eda8 100644 --- a/src/gtk/clipbrd.cpp +++ b/src/gtk/clipbrd.cpp @@ -41,7 +41,6 @@ typedef wxScopedArray wxDataFormatArray; // data // ---------------------------------------------------------------------------- -static GdkAtom g_clipboardAtom = 0; static GdkAtom g_targetsAtom = 0; static GdkAtom g_timestampAtom = 0; @@ -231,7 +230,7 @@ selection_clear_clip( GtkWidget *WXUNUSED(widget), GdkEventSelection *event ) kind = wxClipboard::Primary; } - else if (event->selection == g_clipboardAtom) + else if ( event->selection == GDK_SELECTION_CLIPBOARD ) { wxLogTrace(TRACE_CLIPBOARD, wxT("Lost clipboard" )); @@ -306,6 +305,8 @@ selection_handler( GtkWidget *WXUNUSED(widget), if ( !size ) return; + wxLogTrace(TRACE_CLIPBOARD, "Valid clipboard data found"); + wxCharBuffer buf(size - 1); // it adds 1 internally (for NUL) // text data must be returned in UTF8 if format is wxDF_UNICODETEXT @@ -469,8 +470,6 @@ wxClipboard::wxClipboard() G_CALLBACK (selection_clear_clip), NULL); // initialize atoms we use if not done yet - if ( !g_clipboardAtom ) - g_clipboardAtom = gdk_atom_intern( "CLIPBOARD", FALSE ); if ( !g_targetsAtom ) g_targetsAtom = gdk_atom_intern ("TARGETS", FALSE); if ( !g_timestampAtom ) @@ -492,7 +491,7 @@ wxClipboard::~wxClipboard() GdkAtom wxClipboard::GTKGetClipboardAtom() const { return m_usePrimary ? (GdkAtom)GDK_SELECTION_PRIMARY - : g_clipboardAtom; + : (GdkAtom)GDK_SELECTION_CLIPBOARD; } void wxClipboard::GTKClearData(Kind kind) @@ -595,8 +594,19 @@ void wxClipboard::Clear() bool wxClipboard::Flush() { - gtk_clipboard_store( gtk_clipboard_get( GTKGetClipboardAtom() ) ); - return true; + // Only store the non-primary clipboard when flushing. The primary clipboard is a scratch-space + // formed using the currently selected text. + if ( !m_usePrimary ) + { + GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + + gtk_clipboard_set_can_store(clipboard, NULL, 0); + gtk_clipboard_store(clipboard); + + return true; + } + + return false; } bool wxClipboard::Open() @@ -762,7 +772,7 @@ wxDataObject* wxClipboard::GTKGetDataObject( GdkAtom atom ) return Data( wxClipboard::Primary ); } - else if ( atom == g_clipboardAtom ) + else if ( atom == GDK_SELECTION_CLIPBOARD ) { wxLogTrace(TRACE_CLIPBOARD, wxT("Clipboard data requested" ));