Hacker News new | ask | show | jobs
by efficax 27 days ago
a button that debounces requests should be disabled until the action is complete instead, so you can only click it once until it is ready to be clicked again. debouncing button clicks is a design failure (it makes more sense for things like requests that happen during typing, where you don't want to stop the feedback)
2 comments

I think that if you'd need to debounce requests, it would be better to put it in a pressed and/or highlighted state until the button is ready again. Then you'd indicate to the user that the press was successfully received and that pressing it again won't do any good.

The buttons in an elevator panel typically work this way. They each light up to confirm a pending request to reach a floor. They each turn off when its floor has been reached. And while a button is lit up, pressing it does nothing.

They should be toggles! Every now and then I will press the wrong button and will have to wait for the elevator to stop, open doors, close doors at a floor no one wants off on.

I mean, I haven’t done the usability research, probably there are some good reasons for it’s not a good idea to just make them toggles, but I would find it neat.

Imagine the backlight of the button is broken. Now you enter the elevator and want to go to floor 7, while someone else already pressed the button ;)
There always will be time between the first click and the time the button gets disabled and even more time before the visual representation of the button gets updated to reflect that. Keeping that time so short that it is impossible for a human to click the button again can be very hard.

It would help if GUI elements had a property “automatically disable on click”, removing the need for the “on click handler” to disable the button (in exchange for adding the need to explicitly re-enable it).

I don’t remember seeing GUI libraries that do that, though.

That probably is because it would confuse users if buttons visually get disabled when they click them.

So, the best answer is to visually keep the button enabled, but ignore rapid further clicks. That’s debouncing.

This is a fundamental misunderstanding of how GUIs must necessarily work. There should be no possibility of race conditions if you understand the threading model.

The visual representation updating (greying out button) is a result of disabling the button, not the same thing. In virtually every GUI toolkit I've ever used there is the concept of the main UI thread, and everything that happens (input and display updates) necessarily has to go through that single thread in order to ensure correctness. (This applies to browsers, too.) That's why input goes into a queue, so you can easily do things like:

(All on the main UI thread):

  - Receive click event 1: disable button, start background process. Possibly redraw button UI *but it doesn't matter because the UI display is not the state, it's just a view*.

  - Receive click event 2: nothing happens, button is disabled

  - Background process finishes, posts update to re-enable the button

  - Receive click event 3: disable button, start background process, etc.
Of course, it's never impossible for the user to click a button. They can click on anything under their cursor. The key is giving them feedback to show them what their clicks will do or just did. If you can update the visuals within a frame or two, that's already fast enough to give that feedback.