Page MenuHomePhabricator

ButtonSelectWidget selects last hovered button when mouseup occurs outside of widget
Open, LowPublic

Description

For a simple ButtonWidget, if you mousedown on the button, then move your mouse out of the button, then mouseup, the button action isn't taken (I guess the click event isn't fired?). For example, see the "Remove surface" button in the VE standalone demo.

However, for a ButtonSelectWidget, if you mousedown on a button, then move your mouse out of the group widget altogether, then mouseup, the button you most recently hovered is selected and its action is taken. This means that 1) there is no way to change your mind once you mousedown, except for mousing up on the currently selected option if there is one; and 2) you don't know which action is going to fire because of T101413: ButtonSelectWidget does not update pressed state when mousing over different button than where mousedown occurred

Event Timeline

Catrope created this task.Jun 4 2015, 5:12 PM
Catrope raised the priority of this task from to Needs Triage.
Catrope updated the task description. (Show Details)
Catrope added a project: OOUI.
Catrope added a subscriber: Catrope.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJun 4 2015, 5:12 PM
matmarex renamed this task from ButtonGroupWidget selects leftmost/rightmost button when mouseup occurs outside of widget to ButtonSelectWidget selects leftmost/rightmost button when mouseup occurs outside of widget.Jun 4 2015, 8:42 PM
matmarex updated the task description. (Show Details)
matmarex set Security to None.
matmarex renamed this task from ButtonSelectWidget selects leftmost/rightmost button when mouseup occurs outside of widget to ButtonSelectWidget selects last hovered button when mouseup occurs outside of widget.Jun 4 2015, 8:44 PM

More amusing: if you mousedown on a option in a SelectWidget, move the mouse elsewhere and mouseup on an option of a different SelectWidget, the first SelectWidget tries to have that second option's value set.

$( 'body' ).append(
	new OO.ui.DropdownWidget( {
		menu: {
			items: [
				new OO.ui.MenuOptionWidget( {
					data: 'qwe',
					label: '1. Click and press here'
				} )
			]
		}
	} ).$element,
	new OO.ui.ButtonSelectWidget( {
		items: [
			new OO.ui.ButtonOptionWidget( {
				data: 'asd',
				label: '2. Drag and mouseup here'
			} )
		]
	} ).$element
);

There are 2 potential models here, and the current implementation is mixing them in a bad way.

  1. As the user drags, the item that will be selected when they release the mouse button changes is highlighted in sync with the location of the cursor.
    1. When the cursor leaves the widget while dragging:
      1. The item where dragging started is highlighted (this is what many controls in Linux and Windows do)
      2. The last item to be dragged over is highlighted (this is what OutlineSelectWidget+OptionWidget does)
      3. The item nearest the cursor is highlighted (this is what some OSX list controls do)
    2. When the user releases the mouse button
      1. The highlighted item is selected (This is what OutlineSelectWidget+OptionWidget does)
  2. As the user drags, the item that will be selected when they release the mouse does not change in sync with the location of the cursor.
    1. When the cursor leaves the widget while dragging
      1. The item the drag began at no longer appears pressed or highlighted (this is what most OS provided buttons do)
      2. The item the drag began on continues to appear pressed or highlighted (this is what ButtonWidget does)
    2. When the user releases the mouse button
      1. The item is only selected if the mouse was both pressed and released on the same item (this is what ButtonWidget does)

I think we need to identify the exact behaviors we want to support, and improve ButtonWidget / make SelectWidget to be configurable so that these different modes of interaction can be supported.

One edge case, that might be necessary to test as well, is the behavior of widgets in draggable parent elements.

My guts feeling tells me that lowest abstraction would be not to change the state at all when clicked, dragged and released somewhere outside the click-start area (even when on another clickable area in the same group).

The behavior where, if you click, drag and release, then the last hovered item gets selected, was probably intended for dropdown menus (MenuSelectWidget) and only accidentally started applying to other SelectWidget subclasses. Entries in dropdown menus are usually rather small, making it easier to missclick (which, to increase the annoyance, also closes the menu), which is why various operating systems have the same behavior (although OOUI widgets are generally spacier). I don't think it makes sense or matches user expectations for other widgets, and should probably be removed from them and limited to MenuSelectWidget only (maybe OutlineSelectWidget too, which is somewhat similar).

Jdforrester-WMF triaged this task as Low priority.Apr 20 2016, 10:09 PM