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 748392 - GTK spinbutton does not "snap" to precise range limits (unless step is a binary fraction)
GTK spinbutton does not "snap" to precise range limits (unless step is a bina...
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Widget: GtkSpinButton
2.24.x
Other All
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2015-04-24 01:40 UTC by Jonathan Tait
Modified: 2018-05-02 16:32 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch for gtkspinbutton.c (1.83 KB, patch)
2015-04-24 01:40 UTC, Jonathan Tait
none Details | Review

Description Jonathan Tait 2015-04-24 01:40:15 UTC
Created attachment 302271 [details] [review]
Patch for gtkspinbutton.c

Steps to reproduce:
- create a GtkSpinButton with {value=1.0, lower=0.0, upper=10.0, step=1.0, digits=1}
- use down-arrow to decrement from initial value of 1.0 to (indicated) 0.0

Result:
 value returned by gtk_spin_button_get_value() or passed to callback procedure is actually 0.0000000000000001 (to 16 decimal places)

Cause:
 in file gtkspinbutton.c, procedure gtk_spin_button_real_spin() does not properly apply the EPSILON factor (defined at the start of the file) to the range-limits.

The putative new value is first calculated thus:
  new_value = adj->value + increment;

Then, in the case of a negative increment with wrap disabled, the procedure simply decides the actual new value to be adopted thus:
  new_value = MAX (new_value, adj->lower);

This will correctly limit the new value to the specified range but it does not cater for the scenario where the new value is just a gnat's whisker above the lower limit due to the accumulation of floating-point errors.
(If wrap is disabled, the down-arrow will be greyed-out after this last negative increment by the procedure gtk_spin_button_draw_arrow(); the limit test is effected by subroutine spin_button_at_limit() which does apply EPSILON correctly. The user will not, therefore, have another chance to down-step to the actual lower limit.)  

What the above procedure should be doing is to test whether the putative new value is within-EPSILON-of-or-below the lower limit and, if so, then adopt the lower limit as the new value. Similarly for the upper limit.

If we also apply the same rationale to the cases where wrap is enabled (and eliminate some duplicated and unnecessary code), we are left with the code as presented in the attached patch.

I have tested this patch in GTK+-2.24.27 on Ubuntu 14.04 x64 (with Gimp 2.8.14 as the sole app.) and the new logic seems to cater properly with all circumstances arising (both with and without wrap enabled). However, this will need thorough testing with a range of application programs.

Please note that this also applies to GTK+3  - the data structures have changed, so too some of the names, but the logic is still the same!
Comment 1 Daniel Boles 2017-08-29 22:51:01 UTC
A test case would be great.

As would comparison to https://bugzilla.gnome.org/show_bug.cgi?id=173116 to see whether you think it has the same cause (I'll try to look into this eventually but can't guarantee it)
Comment 2 GNOME Infrastructure Team 2018-05-02 16:32:42 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gtk/issues/549.