After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 734196 - zenity: --info destroys X11 primary selection content, and does not document that either
zenity: --info destroys X11 primary selection content, and does not document ...
Status: RESOLVED FIXED
Product: zenity
Classification: Core
Component: general
3.12.x
Other Linux
: Normal major
: ---
Assigned To: Zenity Maintainers
Zenity Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-08-03 10:59 UTC by Andreas Mohr
Modified: 2015-04-21 08:56 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Workaround/hotfix to avoid loss of foreign X11 primary selection content (1.64 KB, patch)
2014-08-05 10:53 UTC, Andreas Mohr
none Details | Review

Description Andreas Mohr 2014-08-03 10:59:14 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
Comment 1 intrigeri 2014-08-03 11:41:28 UTC
"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.
Comment 2 Andreas Mohr 2014-08-03 16:18:18 UTC
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.
Comment 3 Arx Cruz 2014-08-03 21:00:37 UTC
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
Comment 4 Andreas Mohr 2014-08-05 10:38:23 UTC
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
  • #0 gtk_selection_owner_set_for_display
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkselection.c line 681
  • #1 gtk_clipboard_set_contents
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkclipboard.c line 598
  • #2 gtk_clipboard_set_with_owner
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkclipboard.c line 711
  • #3 gtk_label_select_region_index
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtklabel.c line 5319
  • #4 gtk_label_select_region
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtklabel.c line 5371
  • #5 gtk_label_grab_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtklabel.c line 4452
  • #6 g_cclosure_marshal_VOID__VOIDv
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #7 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #8 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #9 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #10 g_signal_emit
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #11 gtk_widget_grab_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwidget.c line 6997
  • #12 gtk_label_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtklabel.c line 4477
  • #13 _gtk_marshal_BOOLEAN__ENUM
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkmarshalers.c line 269
  • #14 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #15 g_closure_invoke
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #16 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #17 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #18 g_signal_emit
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #19 gtk_widget_child_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwidget.c line 9671
  • #20 gtk_container_focus_move
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkcontainer.c line 2906
  • #21 gtk_container_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkcontainer.c line 2427
  • #22 _gtk_marshal_BOOLEAN__ENUM
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkmarshalers.c line 269
  • #23 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #24 g_closure_invoke
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #25 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #26 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #27 g_signal_emit
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #28 gtk_widget_child_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwidget.c line 9671
  • #29 gtk_container_focus_move
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkcontainer.c line 2906
  • #30 gtk_container_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkcontainer.c line 2427
  • #31 _gtk_marshal_BOOLEAN__ENUM
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkmarshalers.c line 269
  • #32 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #33 g_closure_invoke
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #34 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #35 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #36 g_signal_emit
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #37 gtk_widget_child_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwidget.c line 9671
  • #38 gtk_window_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwindow.c line 6347
  • #39 _gtk_marshal_BOOLEAN__ENUM
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkmarshalers.c line 269
  • #40 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #41 g_closure_invoke
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #42 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #43 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #44 g_signal_emit
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #45 gtk_widget_child_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwidget.c line 9671
  • #46 gtk_window_move_focus
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwindow.c line 6364
  • #47 g_cclosure_marshal_VOID__ENUMv
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #48 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #49 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #50 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #51 g_signal_emit_by_name
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #52 gtk_dialog_map
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkdialog.c line 474
  • #53 g_cclosure_marshal_VOID__VOIDv
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #54 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #55 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #56 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #57 g_signal_emit
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #58 gtk_widget_map
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwidget.c line 4353
  • #59 gtk_window_show
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwindow.c line 4840
  • #60 g_cclosure_marshal_VOID__VOID
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #61 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #62 g_closure_invoke
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #63 ??
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #64 g_signal_emit_valist
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #65 g_signal_emit
    from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  • #66 gtk_widget_show
    at /build/gtk+3.0-iSkrqS/gtk+3.0-3.8.4/./gtk/gtkwidget.c line 4161
  • #67 zenity_util_show_dialog
    at util.c line 423
  • #68 zenity_msg
    at msg.c line 168
  • #69 main
    at main.c line 66


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.
Comment 5 Andreas Mohr 2014-08-05 10:53:31 UTC
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.
Comment 6 Arx Cruz 2015-04-21 08:56:57 UTC
Fixed on master.