Opened 12 years ago

Last modified 4 years ago

#8883 new enhancement

Text inputs don't follow Haiku "live update" UI paradigm.

Reported by: jstressman Owned by: stippi
Priority: normal Milestone: R1.1
Component: User Interface Version: R1/Development
Keywords: Cc: ttcoder
Blocked By: #3123 Blocking:
Platform: All

Description

This appears to be related to the same issue being discussed in #3123 but I'm opening this as a new ticket because that one is 4 years old, denies the problem, and says it's just Playground specific when I don't believe it is. This seems to be a fundamental design problem that is affecting multiple applications and parts of the OS.

An easy way to reproduce this is to open the Backgrounds preferences and choose to manually place your background.

Change one of the X Y coordinate numbers and nothing will happen until you change focus to somewhere else (by hitting TAB or clicking in another input box etc). Only then will the Apply button become available. In fact, using ENTER to make your change "live" is even worse, as for me it applies the first change to by making the Apply button active for a split second and then activating it... when it wasn't active... and then subsequent changes DON'T work with ENTER... or even tabbing to change focus... so you end up having to click around and type different numbers in etc to get it working again... it's a mess.

This is a systematic problem that affects other applications as well. Icon-O-Matic for instance is doubly affected by this in the color switcher... when entering a hex color the color isn't changed until you change focus... and if you're changing to one of the RGB numbers to get the HEX color to register, the RGB number you switched focus to ALSO won't change until you change focus from THAT one as well... so it takes 2 focus changes to actually have everything display correctly.

The correct behavior would apparently be to announce the change as soon as it happens and make the appropriate updates per keystroke or whatever. So as soon as you change the number, the option to Apply it becomes available (and the location in the preview image changes etc), or in the Color Picker the updated color and correct related numeric value fields would be shown, etc... perhaps after a tiny time out so that unnecessary processing isn't done that jams things up.

Is there some reason why the default behavior should be this unintuitive across the board, leading to further problems in many places like this? It would seem like the default behavior should be a "live update", and only in special cases would you want to manually force an update by making the user do extra work.

The only cases where I can see a user NOT wanting to see a live update of their changes is something where it would be very CPU intensive to recalculate something based on those changes. And for something like that it would seem better to make that the case where the programmer would need to say "DON'T live update this" rather than a default live update behavior.

All this seems even more the case considering that the rest of the OS UI seems focused on a paradigm of live updating without requiring extra work to apply changes etc. Correct? That makes this behavior really unintuitive from my perspective and in conflict with the rest of expected UI function of the OS.

BUT... I'm not a programmer, so take that as you will... but having to do all this focus changing throughout Haiku to work around this problem is unintuitive and unpleasant from a user perspective, and apparently is just as unintuitive for other programmers because it seems so overlooked and problematic at the moment.

hrev44524 gcc2h

Change History (6)

comment:1 by jstressman, 12 years ago

A bit more on that thought...

This seems to be the kind of mentality that is used partially in things like the Backgrounds preferences.

For instance the preview mode. What you would intuitively want to happen is that when you changed the numeric X or Y input, you would want to see the little preview image change to show your location change. As soon as you change that number, you also want to see the "Apply" button become highlighted to show that you can now apply the changes you've made in your preview to your actual desktop. The CPU intensive part of the process that is being avoided until necessary by allowing a live update of the smaller non-CPU-intensive preview.

The same kind of "live update" mentality would appear to apply to the Color Picker as well... you go into the color picker, and enter a hex number for instance... so you have it not update until all 6 letters/numbers are entered, but at that point, after all 6 are typed in, it updates the numeric values for the RGB etc and also updates the changed color preview. This way you can easily type, backspace, type etc... to get the color just right without having to do extra work... and then when you're ready you then click "OK" to actually apply that color change (and do whatever potentially more CPU intensive changes need to be made).

In both these cases (and I'm sure many others), the intuitive desired functionality is a live update of some sort based on changes to those inputs. Not hitting enter, or having to change focus after each small change etc.

Maybe the reason this isn't done by default is that you still programmatically have to define what the live update actually does? Like I said, not being a programmer myself I don't really understand the underlying reason things are the way they are. I'm just speaking from a user perspective.

comment:2 by stippi, 12 years ago

There is a short version and a long version of my reply...

The short version is this: This cannot be fixed on a system-level (i.e. inside BTextControl or BTextView), and the problems you mention need to be fixed at the application level, in each individual application. Really.

The long version: Consider the examples you gave: Inputting the placement of the desktop background, changing the color in Icon-O-Matic... BTextControl has no idea what makes valid input. Suppose your background is currently located at 510 pixels to the right. You want to change that to 515 pixels. Suppose you do that by deleting the last number, so the input now reads "51". Your computer is most likely fast enough to quickly render the preview at 51 pixel horizontal offset. Shortly after that, you enter the 5, and now the background is showing at 515. Suppose you enter "515" by clicking into the text field, focusing all text and overwriting the selection with 5, 51, and finally 515. So your background would jump from 5, then 51 to finally 515 pixels offset. I consider that visually irritating, especially since your attention should be on the text input.

Consider Icon-O-Matic. The same problems apply there. Should the color preview go almost black, since you entered "2", then a dark grey, since you entered "23", then switch to almost white since you finally entered "230"?

Both of these apps *should* register for text modifications, and adopt the changed input *after a short delay*. Probably an application specific delay, even.

Why can't the BTextControl send the value changed message after a short delay in all apps? Consider the following use case: You rename a file in Tracker. Renaming can be a destructive operation. If you enter a name already taken by another file, Tracker asks you if you want to overwrite that file. Imagine you enter a new file name, where the first part of the name matches the name of another file. During entering the name, you make a short pause to think. But that's already enough to trigger the universal delay. Tracker wants to apply a live preview, but that results into asking you whether you want to overwrite the other file... Maybe this is an exception to the "rule" of when to apply changes live, but BTextView or BTextControl cannot know the context in which they are used, so they cannot send the same message which normally means "input finished" shortly after the last keypress.

BTW, I have recently worked with SWT, which uses native platform widgets on all platforms. There, too, text inputs work the exact same way as in Haiku. The programmer can register for "modified" events, sent after each key press, and input is usually considered done, when the focus changes outside the text input, or the user pressed enter.

That being said, I think we could reduce the problem by adding optional functionality to BTextView where it can send a "text changed" event after a short delay after the user last pressed a key. That would be in addition to the "text modified" event that applications can already register for (sent for every key press) and the "value changed" message of BTextControl, sent after "enter" or "focus out".

Obviously this still means each individual application needs to be changed to make use of this new feature. And all it saves is implementing the "delay after last key press" in each app. It would certainly be worthwhile to do that and to fix the problems that you mention.

comment:3 by jstressman, 12 years ago

Thanks for the reply Stephan. I better understand the programmatical aspect of it now. :)

Should I enter tickets for the places I spot these issues in different apps, or wait until after this potentially gets updated and see which ones are still around?

comment:4 by pulkomandy, 10 years ago

Blocked By: 3123 added

A list of other affected apps would be appreciated. Adding #3123 as a first "blocker" for this ticket.

comment:5 by ttcoder, 4 years ago

Cc: ttcoder added
Type: bugenhancement

That being said, I think we could reduce the problem by adding optional functionality to BTextView where it can send a "text changed" event after a short delay after the user last pressed a key

This. I have quite a bit of code dealing with SetMessage()/SetModificationMessage() in my UI framework and was once tempted to add a one-fire BMessageRunner( MSG_INVOKED @ 500 ms ) that would be 'reset' on each keystroke, until it's no longer reset and finally sends its message, but never got around to it. Would be better if the BTextView/Control API is extended to do that on its own indeed.

comment:6 by pulkomandy, 4 years ago

Milestone: R1R1.1
Note: See TracTickets for help on using tickets.