GNOME Bugzilla – Bug 316156
selection tool: modifiers pressed before click should only do one thing.
Last modified: 2008-01-15 13:00:21 UTC
Pressing a modifier key with a selection tool before beginning the drag does two things. Eg, shift constrains to square AND adds to the selection. The system of keyboard modifiers for the selection tools would be considerably simpler to use and understand if this behaviour were changed. This thread on Open Usability explains fully (http://openusability.org/forum/forum.php?thread_id=634&forum_id=462), but here is a summary of what should happen: - modifier present when mouse button is pressed should be only counted as a boolean modifier (this is what needs to be changed) - modifier pressed after mouse button is pressed should only count as a shape modifier (this already happens)
I think we should consider doing this change for 2.4. The current behaviour of the selection tools has been a constant source of confusion.
Raising priority to Urgent, because this really needs to be addressed for 2.4.
Raising severity more, to Blocker.
Note: the real purpose of this bug report now is as a reminder to put back the functionality allowing Shift and Control to constrain aspect ratio and expand-from-center when pressed after the button is already down.
I'm trying to figure out how to implement this. From Peter Sikking's blog, I have the impression that Peter, Sven, and Mitch sat down and worked out how to do it, but not knowing what they came up with, I'll give my own ideas. The basic problem is that modifier-key events are not sent to tools while button1 is down. That needs to be changed, but it needs to be done in a way that doesn't break a bunch of other tools. It seems to me that the most straightforward approach is: 1) add to the GimpToolControl struct a Boolean wants_modifier_events field, set to TRUE if and only if the tool wants to get modifier events while button1 is down. 2) in the modifier_key() method of gimptool.c, change it to invoke the specific tool's modifier_key method if either button1 is up or wants_modifier_events == TRUE. 3) change gimpdisplayshell-callbacks.c to propagate Shift and Ctrl key modifier events regardless of button state. I'm sure there will turn out to be problems with this approach -- I'm more looking for feedback than anything else.
We only worked out the user interface part, not how to implement it. I think that Mitch already had an idea but he probably won't be back until next week to tell. About your proposal: I don't see why we should make this optional. All tools should behave correctly for modifier changes that occur while the mouse button is pressed. I would prefer to review all tools than to complicate things with another toggle. But then, you have probably spend more time thinking about this than me.
I'm not sure you'd want something like dodge/burn to change in mid-stroke, and being able to let go of CTRL to set it to dodge is useful. The same goes for tools that switch to the eyedropper with CTRL.
Re comment #6, I agree with you, but I think this may be too intrusive for the 2.4 cycle at this point. Thinking about this some more, I see that it can be done entirely within the GimpRectangleTool code, although in a somewhat hackish way. The idea would be to introduce two new Boolean variables to GimpRectangleTool, called shift_constraint_enabled and ctrl_constraint_enabled. These would be set to FALSE on button press if the corresponding key is down at that time, TRUE otherwise. In the motion function, a variable would be set to TRUE if the corresponding key is up. Then a contraint would be activated if and only if the modifier key is down and the constraint_enabled variable is TRUE -- this combination would mean that the key had been pressed *after* mouse button1 was pressed. It seems to me that this approach would be better for 2.4.
We also need the change to implement the tool statusbar messages properly. I am not saying that it should be done in a way that breaks all tools, but all tools should have a chance to react to modifier changes while the mouse button is pressed.
I don't know if there's a bug open for this (I can't find one) but a current problem with modifier keys and the selection tools is that they aren't noticed until you move the mouse. Eg, when you drag a rectangle, then stop the mouse, then press SHIFT to constrain to square, the shape should change. Currently you have to move the mouse to make it happen. (Apologies if this isn't relevant.)
Progress on this, committed to HEAD: 2006-08-21 Bill Skaggs <weskaggs@primate.ucdavis.edu> * app/display/gimpdisplayshell-callbacks.c: allow modifier key events for Shift and Control to be propagated even if button1 is down. * app/tools/gimpclonetool.c * app/tools/gimpcroptool.c * app/tools/gimpforegroundselecttool.c * app/tools/gimpmovetool.c * app/tools/gimppainttool.c * app/tools/gimpvectortool.c: change modifier_key method to prevent any bad consequences. * app/tools/gimprectangletool.[ch]: add modifier_key handler, and use it to toggle "make-square" if Shift is pressed while button1 is down, and "fixed-center" if Control is pressed while button1 is down. * app/tools/gimprectangleselecttool.c (gimp_rectangle_tool_modifier_key): call rectangle tool modifer_key method after chaining up. I don't consider this the end of the story, so I will leave the bug report open.
Please use Milestone + Priority==Urgent instead of Severity==Blocker.
Fixed in CVS: 2006-09-12 Michael Natterer <mitch@gimp.org> Added new tool API for modifier key events while the tool is active and implement it in the rect select and crop tools. Fixes bug #316156 and bug #355302. * app/tools/gimptool.[ch]: added GimpTool::active_modifier_key() and public function gimp_tool_set_active_motifier_state(). Remember the active_state at button_press and reset it on button_release. Ignore releases of modifiers that were pressed at button_press (but only ignore them once). * app/tools/tool_manager.[ch]: added wrapper tool_manager_active_modifier_state_active(). * app/display/gimpdisplayshell-callbacks.c (gimp_display_shell_events): return FALSE for all modifiers even when mouse button 1 is pressed. (gimp_display_shell_canvas_tool_events): when bouse button 1 is pressed *and* the tool is active, dispatch the new active_modifier events to tools. * app/tools/gimpcroptool.c * app/tools/gimprectangleselecttool.c * app/tools/gimprectangletool.[ch]: implement active_modifier_key() instead of modifier_key().