GNOME Bugzilla – Bug 734196
zenity: --info destroys X11 primary selection content, and does not document that either
Last modified: 2015-04-21 08:56:57 UTC
Hi, filing upstream report of existing Debian bug at https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=742211 I might find the time soon to fix this myself, but no promises ;) (not an active GNOME repo user, thus I'll need to get all that stuff up and running; hoping to get away cheaply with an apt-get source and a diff) Thanks, Andreas Mohr ========== Package: zenity Version: 3.8.0-1 Severity: important Justification: data loss Dear Maintainer, * What led up to the situation? Select something with left mouse key, then run e.g. sleep 10 && /usr/bin/zenity --info --text foobar or sleep 10 && /usr/bin/zenity --error --text foobar * What exactly did you do (or not do) that was effective (or ineffective)? * What was the outcome of this action? Witness your primary selection getting zilched, nullified as soon as zenity is launched, on this environment and some others (bug discovered on u1204LTS). * What outcome did you expect instead? Middle mouse button ought to still have been able to re-paste the left-button-copied content, just like it *does work* for sleep 10 && /usr/bin/zenity --entry (!!) sleep 10 && /usr/bin/zenity --file-selection (!!) sleep 10 && /usr/bin/kdialog --msgbox foobar (4:4.11.3-1) Fooled once, fooled twice, but then I got wise ;) Severity important since it's *very* annoying to lose copy&paste content of possibly already vanished or forgotten origin content (this problem does not apply to the case of windows having been closed though since it appears their selection is gone anyway), seemingly without any indication by zenity on why this is the case, and why for *certain* zenity modes only (so, this problem should either be fixed, or properly documented). Anyway, in my case it was an annoyance at least a couple times already when losing mouse selection content midstream due to having chosen to use zenity as a cron-based reminder message launcher... Thanks a lot for your work, Andreas Mohr -- System Information: Debian Release: jessie/sid APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 3.12.0-rc2+ Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages zenity depends on: ii libc6 2.17-3 ii libgdk-pixbuf2.0-0 2.28.2-1 ii libglib2.0-0 2.38.2-5 ii libgtk-3-0 3.10.7-1 ii libnotify4 0.7.4-1 ii libpango-1.0-0 1.36.0-1+b1 ii libwebkitgtk-3.0-0 2.2.5-1 ii libx11-6 2:1.6.0-1 ii zenity-common 3.8.0-1 zenity recommends no packages. zenity suggests no packages. -- no debconf information -- debsums errors found: sh: 1: /usr/sbin/dpkg-divert: not found
"critical" severity seems a bit exagerated on this one. Severity hyperboles generaly don't help upstream developers be in a good mood when discovering a new bug report.
I chose "critical" since "data loss" was part of this level's characterization. However admittedly we're talking of usually mild data loss here (in many cases people would remember what they selected, as opposed to e.g. full-disk data loss). I just grabbed zenity source and built it, yet then (post-build!) found that whenever removing the <property name="selectable">True</property> line from <object class="GtkLabel" id="zenity_info_text"> in zenity.ui file, the dialog's text label becomes non-selectable, *and the X11 primary selection's content remains alive*. So that seems to point at a selection issue in GTK core areas!? (IMHO it's simply still not acceptable to have "selectable" text nullify prior selection content - it should simply replace the selection the moment that the user does a new selection, and not a nanosecond before that event) I'm now trying to whip up a quick Python example to cross-verify these observations.
Hello, Thanks for the bug, I'm moving to another country, and I will be with restrict access to internet for the next two weeks. I will take a look when I settle down. Kind regards
I've now installed libgtk-3-0-dbg and found out that selection destruction also depends on <property name="can_focus">True</property> being available. I then started another gdb session with set args --info --text foobar , and then did b gtk_selection_owner_set b gtk_selection_owner_set_for_display run I then hit gtk_selection_owner_set_for_display (gdb) bt full
+ Trace 233929
fin:ishing that function entry then made the prior selection disappear, which confirms that it's processing within this function which is responsible. I then had a look at static void gtk_label_grab_focus (GtkWidget *widget) { GtkLabel *label; gboolean select_on_focus; GtkLabelLink *link; label = GTK_LABEL (widget); if (label->select_info == NULL) return; GTK_WIDGET_CLASS (gtk_label_parent_class)->grab_focus (widget); if (label->select_info->selectable) { g_object_get (gtk_widget_get_settings (widget), "gtk-label-select-on-focus", &select_on_focus, NULL); if (select_on_focus && !label->in_click) gtk_label_select_region (label, 0, -1); } else { if (label->select_info->links && !label->in_click) { link = label->select_info->links->data; label->select_info->selection_anchor = link->start; label->select_info->selection_end = link->start; } } } of gtklabel.c of http://www.cs.binghamton.edu/~sgreene/cs360-2011s/topics/gtk+-2.20.1/gtk/ where I found that it checks the gtk-label-select-on-focus property, which seems to be TRUE for our case, which is why it proceeds with calling into the selection-destroying gtk_label_select_region(). OK, so in general for this issue we have a backtrace of: gtk_label_grab_focus -> gtk_label_select_region -> gtk_label_select_region_index -> gtk_clipboard_set_with_owner -> gtk_clipboard_set_contents -> gtk_selection_owner_set_for_display But note that after the first gtk_label_select_region(), gtk_dialog_map() does another unconditional gtk_label_select_region(..., 0, 0) on that label!?!? (to choose the dialog's focussed widget) But even *before* that second gtk_label_select_region(), the primary selection is already zilched. This might possibly be because the dialog window is not actually mapped yet at the first invocation, thus we even never end up with the label string (here: "foobar") in the primary selection (to add insult to injury). And this second gtk_label_select_region(): gtk_dialog_map() -> gtk_label_select_region(..., 0, 0) -> gtk_label_select_region_index() -> gtk_clipboard_clear() *actively* clears primary selection! (i.e. a manually chosen selection will be unavailable from that moment) I'm now wondering whether we're staring in the face of toolkit handling bugs in the case of clipboard processing relating to GtkLabel widget selection changes. After all why would focus handling and/or tab group handling changes need to destroy a pre-existing foreign-application primary selection, prior to actual *user-side* manual selection changes?? Possibly this issue should thus be forwarded to the relevant GTK package instead... Side note: I have to admit that I've already had major PITA (quite a bit worse than most other "interesting" GUI widget areas) with GTK's behaviour in this area (selection behaviour of wxWidgets wxTextCtrl, in wxGTK port), which caused me to have to implement multiple workarounds against "unexpected" selection behaviour there.
Created attachment 282542 [details] [review] Workaround/hotfix to avoid loss of foreign X11 primary selection content Setting the gtk-label-select-on-focus property of the label widget to FALSE manages to avoid the primary selection loss which occurs on every launch of zenity --info --text foobar. Further docs see source (patch). Patch against zenity 3.8.0 as available on my Debian testing, but given some luck it should easily apply to trunk, too. While this is a workable hotfix, this issue quite likely should still end up as an issue report of GTK libraries proper, if only to have a clarifying discussion about why clipboard / primary selection / widget focus behaviour is (possibly rightfully) implemented the (rather annoying) way it is.
Fixed on master.