Re: Best practice query: Entry field "user's done editing" handling?



On Mon, 2013-12-23 at 09:41 +0000, Phillip Wood wrote:
On 16/12/13 21:27, Chris Angelico wrote:

I have a form with a whole pile of entry fields (GTK2.Entry), and I
need to do some processing (and save the edit) whenever the user's
edited a field and is now done editing. Is there a standard way to
recognize this? I'm thinking of something like the VX-REXX "Verify"
event, which fires on a changed entry field when focus moves to
another control on the same window, but not if focus moves to another
window altogether.

Currently, I'm hooking focus-out-event signals and checking the
current text to see if it differs from a saved copy of the text. I'd
rather not save every time a 'changed' signal comes through, as that
would be hopelessly inefficient most of the time.

In your focus-out handler you can call gtk_widget_is_focus on the entry, 
if it returns true then the focus has passed to another window and you 
don't need to do anything. If it returns false then it's possible that 
the user has popped up the context menu rather than moved to a different 
control in the same window. Keeping track of this is a bit more 
complicated. You need to connect to the "popup-menu" signal with the 
entry as the user_data and do something like

g_object_set_data (G_OBJECT(entry), "in-popup", G_INT_TO_POINTER(TRUE));
g_signal_connect (menu, "unmap", on_menu_unmap, entry);

in on_menu_unmap
g_object_set_data (G_OBJECT(entry), "in-popup", G_INT_TO_POINTER(FALSE));
g_object_set_data (G_OBJECT(entry), "popdown-id", G_UINT_TO_POINTER 
("g_timeout_add (500, popdown_cb, entry)));

in popdown_cb
if (!gtk_widget_is_focus(entry))
   do_processing

In the focus out handler you can check in-popup for the entry, you 
should also remove the timeout function to avoid doing the processing 
twice. The timeout ensures that if the user transfers the focus from the 
context menu directly to another control you still save the result. 
Gnome shell seems to prevent the user from doing that but other window 
managers may not. This is the scheme that GtkCellRendererText uses to 
keep track of the context menu.

It's my understanding that committing user data in a focus-out handler
is a common mistake, and it will bite you with multiple toolkits, not
only GTK+.

In Glade we avoid this, primarily because of scenarios such as the
following:

  o User selects widget in the workspace (or inspector treeview)
  o This causes the property editor to show up, containing some entries
  o The user then modifies an entry (let's imagine we're naive and
    ignore the new text in the entry)
  o Then the user goes ahead and selects another widget, user is happy,
    they changed the entry value and expect it to persist.
  o Selecting the new widget will cause a new set of properties to be
    loaded up in the property editor, the old property editor
    will be detached from the GladeWidget it was editing (i.e. the
    view/controller is detached from the model, something new is loaded)
  o All of the above happens over the course of "selecting a new
    widget", typically this is a mouse click... what happens next ?
  o A new focus widget is set and the old entry receives a "focus out
    event"

We don't want to be chasing down scenarios where this could possibly
break, so the best thing we can do is commit everything immediately
(you could have an asynchronous layer in your data model which handles
this, if performance or flash wear is an issue).

Another existing bug, along the same parallel, is values committed in
cell renderers. The user doesnt always know they need to press "Enter"
or somehow cause the "edited" signal to fire on a cell renderer, we
continuously receive bug reports related to "I entered a value in a cell
renderer and selected something else, Glade doesnt remember the value
I put in the cell renderer".

I strongly advise against usage of "focus out" events for committing
data, if your application is simple enough now that it doesnt cause
problems, it will certainly cause you problems later as your
application gains complexity.

Cheers,
     -Tristan




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]