Bug 144549

Summary: [GTK] Paste data is removed from clipboard when closing browser tab
Product: WebKit Reporter: Michael Catanzaro <mcatanzaro>
Component: WebKitGTKAssignee: Michael Catanzaro <mcatanzaro>
Status: RESOLVED FIXED    
Severity: Critical CC: andersca, cgarcia, mcatanzaro, mrobinson
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: Linux   
See Also: https://bugs.webkit.org/show_bug.cgi?id=144547
Attachments:
Description Flags
Patch
cgarcia: review-
Different approach
none
Another approach mrobinson: review+

Description Michael Catanzaro 2015-05-03 09:34:44 PDT
Select some text on this page, right click, Copy. Paste it into another app. Paste works great, yay! Now do the same again, but close the current tab (in Ephy, or close MiniBrowser if you're using that). There is no longer any data to paste. If the user was copying, say, a long Bugzilla reply, he is now quite frustrated that his copied data was deleted.
Comment 1 Michael Catanzaro 2015-07-16 19:20:42 PDT
Created attachment 256948 [details]
Patch
Comment 2 Martin Robinson 2015-07-16 19:59:11 PDT
Comment on attachment 256948 [details]
Patch

Hrm...I'm not sure about this. I think there can be multiple Pasteboards at one time. Is it possible to simply store the clipboard data as soon as a "copy" occurs in a WebView?
Comment 3 Carlos Garcia Campos 2015-07-16 23:28:19 PDT
(In reply to comment #0)
> Select some text on this page, right click, Copy. Paste it into another app.
> Paste works great, yay! Now do the same again, but close the current tab (in
> Ephy, or close MiniBrowser if you're using that). There is no longer any
> data to paste. If the user was copying, say, a long Bugzilla reply, he is
> now quite frustrated that his copied data was deleted.

Yeah, I've suffered this a lot of times, and I always wondered why. Thanks for working on this.
Comment 4 Carlos Garcia Campos 2015-07-17 01:26:30 PDT
Comment on attachment 256948 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=256948&action=review

> Source/WebCore/platform/gtk/PasteboardGtk.cpp:96
> +    if (hasData()) {
> +        ASSERT(m_gtkClipboard);
> +        gtk_clipboard_store(m_gtkClipboard);
> +    }

This is not correct, and not the correct place either. First you are asserting m_gtkClipboard is not nullptr, but it can be nullptr. In case of private or drag and drop Pasteboard the clipboard will be nullptr, and the data object might have data. Also, I don't think we need to check if there's data first, since that retrieves the data, something that gtk_clipboard_store will do anyway. And finally, this should be done only when the process finishes, not everytime a Pasteboard object is deleted. GTK+ stores all clipboards in gtk_main or gtk_application_shutdown when the main loop finishes. We don't use gtk_main() in the web process, that's why it has never worked.
Comment 5 Carlos Garcia Campos 2015-07-17 02:33:58 PDT
Created attachment 256963 [details]
Different approach

This approach adds API to PasteboardHelper to store all clipboards that is used from WebProcessMain::platformFinalize(). This doesn't currently work due to bug #147036, though.
Comment 6 Martin Robinson 2015-07-17 07:16:16 PDT
Comment on attachment 256963 [details]
Different approach

View in context: https://bugs.webkit.org/attachment.cgi?id=256963&action=review

> Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp:70
> +        PasteboardHelper::storeAllClipboards();
> +

How exactly does gtk_clipboard_store work? Does it override the current X11 selection?
Comment 7 Carlos Garcia Campos 2015-07-17 08:50:05 PDT
(In reply to comment #6)
> Comment on attachment 256963 [details]
> Different approach
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=256963&action=review
> 
> > Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp:70
> > +        PasteboardHelper::storeAllClipboards();
> > +
> 
> How exactly does gtk_clipboard_store work? Does it override the current X11
> selection?

I don't know the details, the doc says "Stores the current clipboard data somewhere so that it will stay around after the application has quit.", and GTK+ does that in gtk_main (once the loop finishes) and gtk_application_shutdown for all applications using gtk_main or GtkApplication.
Comment 8 Martin Robinson 2015-07-17 08:55:31 PDT
This seems okay to me, but could you do a quick test that this does not override the clipboard contents if the selection belongs to another application when the WebKitGTK+ exits?
Comment 9 Michael Catanzaro 2015-07-17 09:03:37 PDT
Thanks Carlos, your patch looks better indeed.

(In reply to comment #7)
> I don't know the details, the doc says "Stores the current clipboard data
> somewhere so that it will stay around after the application has quit.", and
> GTK+ does that in gtk_main (once the loop finishes) and
> gtk_application_shutdown for all applications using gtk_main or
> GtkApplication.

It goes in the ICCCM clipboard manager:

http://www.freedesktop.org/wiki/Specifications/clipboard-manager-spec/
http://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.html

(I have no clue what that is in GNOME; probably mutter I would guess.)

(In reply to comment #8)
> This seems okay to me, but could you do a quick test that this does not
> override the clipboard contents if the selection belongs to another
> application when the WebKitGTK+ exits?

Oh good point. Only the CLIPBOARD selection should be saved, not PRIMARY. But, I am not sure if GTK+ makes sure to ignore gtk_clipboard_store() when called on PRIMARY, or if it's our responsibility to not do that. Probably that will simply never happen, because surely we won't have PRIMARY at the same time as another app does? I am glad PRIMARY does not exist in Wayland; it really complicates things, and I don't pretend to understand it.
Comment 10 Carlos Garcia Campos 2015-07-17 09:31:35 PDT
Yes, primary selection is not affected. This patch makes WebKitGTK+ behave like any other GTK+ application.
Comment 11 Carlos Garcia Campos 2015-07-20 09:54:30 PDT
Thanks for the review, unfortunately this patch doesn't work if patch attached to bug #147036 isn't landed first.
Comment 12 Carlos Garcia Campos 2015-07-29 06:18:37 PDT
Another way to solve this without depending on bug #147036 that it seems it's not going to be fixed, would be making PasteboardHelper singleton destructible, and store the clipboards in the destructor. The pasteboard helpers created in other processes than the web process won't be a problem, since they won't have any clipboard registered. And another way to solve this, would be to move all the pasteboard handling to the ui process so that only the UI process writes into the clipboard, and the clipboard will be saved when gtk_main_quit or gtk_application_shutdown is called, but that would be a lot more work.
Comment 13 Carlos Garcia Campos 2015-07-29 06:39:45 PDT
Created attachment 257747 [details]
Another approach
Comment 14 Michael Catanzaro 2015-07-29 07:35:26 PDT
(In reply to comment #12)
> Another way to solve this without depending on bug #147036 that it seems
> it's not going to be fixed, would be making PasteboardHelper singleton
> destructible, and store the clipboards in the destructor.

This seems cleaner to me anyway.
Comment 15 Carlos Garcia Campos 2015-07-29 08:32:38 PDT
Comment on attachment 256963 [details]
Different approach

Clearing flags here then
Comment 16 Carlos Garcia Campos 2015-07-29 23:41:39 PDT
Committed r187580: <http://trac.webkit.org/changeset/187580>