GNOME Bugzilla – Bug 748392
GTK spinbutton does not "snap" to precise range limits (unless step is a binary fraction)
Last modified: 2018-05-02 16:32:42 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!
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)
-- 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.