GNOME Bugzilla – Bug 315280
Cannot input characters in a editable cell of treeview with a input method which uses a preedit window.
Last modified: 2018-02-10 03:24:27 UTC
We cannot input characters in a editable cell of treeview with a input method which uses a preedit window. When the preedit window opens, the editable cell loses the focus, and becomes not edibable. The data capture with the input method does not work. I test with : (i) gtk-demo (version gtk 2.4.6) (ii) im-ja input method version 1.4 >> GTK_IM_MODULE="im-ja" gtk-demo >> select "TreeView-> Editable Cells" >> select a cell >> right click --> select "Unicode input" or "symbol input" => a preedit window opens, => the cell becomes not editable >> At the end of the input in the preedit window, gtk-demo failed. I think that the problem is similar with all input methods which use a preedit window. Proposal : In the file gtk/treeview.c -> function : static void gtk_tree_view_stop_editing (GtkTreeView *tree_view, gboolean cancel_editing) { ... <if "preedit window of input method is open" then return> /* I don't know which "flag" indicates that a input method is in use */ ... } Pascal
I'll raise the priority of this bug as it is pretty bad for input methods. For example, in the file chooser you can't create a new folder if you have to use an input method when entering the folder's name. (And in Nautilus, you can't create a new folder in list view, either.) The problem is basically this, from gtkcellrenderertext.c:gtk_cell_renderer_text_start_editing(): priv->focus_out_id = g_signal_connect_after (priv->entry, "focus-out-event", G_CALLBACK (gtk_cell_renderer_text_focus_out_event), celltext); And later... static gboolean gtk_cell_renderer_text_focus_out_event (GtkWidget *entry, GdkEvent *event, gpointer data) { GtkCellRendererTextPrivate *priv; priv = GTK_CELL_RENDERER_TEXT (data)->priv; if (priv->in_entry_menu) return FALSE; g_object_set (entry, "editing-canceled", TRUE, NULL); gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry)); gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry)); /* entry needs focus-out-event */ return FALSE; } That is, GtkCellRendererText takes "focus out from the entry" to mean "cancel the editing". This does not make sense. It doesn't let you (e.g.) switch to another window to copy some text to the clipboard, so that you can later go back to the cell you were editing and paste it. The cell renderer should use an Escape keystroke to cancel editing, not a focus-out event.
*** Bug 628027 has been marked as a duplicate of this bug. ***
*** Bug 552902 has been marked as a duplicate of this bug. ***
By the way, in the file chooser we still have a hack for bug #154921 - it may be good to investigate that while this bug is being fixed.
I can type Japanese in Editable Cells in gtk-demo without any problems, GTK+ 2.22.1, iBus 1.3.9.
Created attachment 213424 [details] [review] GtkCellRendererText: don't cancel edit on focus-out We can lose the focus in a number of situations in which we really should continue the edit: input methods popping up a window or the case of the user switching to another window to copy some text that they want to paste. It is still possible to cancel the edit by clicking on another area of the treeview or by hitting the escape key (verified in the treeview editing example in gtk-demo and in the file chooser).
Note that things are unfortunately not as easy as that and this is the main reason why this problem has not been properly resolved (yet). The cancel on focus-out was added back in 2002 to solve a data-loss bug, see bug 87811. Without focus-out, the problem is that you can start editing, move the mouse to the Okay button and click it. The edited information will never be saved, unless the dialog implements special handling for this when it is closed (destroyed or hidden, and you would need to figure whether okay, cancel or window close was pressed and distinguish behavior on these cases). Similar issue in bug 82405. Related question, what happens if you have a window with two tree views, and both have editing active at the same time? There are also other bugs in which the current focus-out behavior has shown to be a problem: see bug 164494. So sometimes the focus-out behavior is preferred, sometimes it is not. The fact that this makes pre-edit windows completely useless is a strong argument for not stopping editing at focus-out. But making this change does require a solution for the data loss bugs, otherwise some applications will clearly regress. If it is decided that applications should start to handle this themselves, this needs to be communicated clearly.
(In reply to comment #7) (Quoting out of order so I can group ideas...) > The cancel on focus-out was added back in 2002 to solve a data-loss bug, see > bug 87811. Without focus-out, the problem is that you can start editing, move > the mouse to the Okay button and click it. The edited information will never > be saved, unless the dialog implements special handling for this when it is > closed (destroyed or hidden, and you would need to figure whether okay, cancel > or window close was pressed and distinguish behavior on these cases). > > Similar issue in bug 82405. > There are also other bugs in which the current focus-out behavior has shown to > be a problem: see bug 164494. Summarizing the bugs above: bugs #87811 and #82405 - I type in a cell, and my data is ignored when I click the dialog's OK button. bug #164494 - I click "Create folder" in the file chooser, an editable "Type name of new folder" appears. If I switch the focus to another window (say, to consult something briefly), a folder named "Type name of new folder" is created. The first bugs are the most pressing, as they silently cause the cell renderer to ignore what you typed - you think that clicking OK would commit everything and close the dialog, but this doesn't happen. The more mundane case is that cancel-on-focus-out makes it hard to cut&paste while editing the cell. The second bug is a file chooser oddity. Nowadays I'm thinking that "Create folder" in the file list is not such a good idea, at least not without a clear indication of *when* the folder will be created. The problem of accidentally creating a folder called "Type name of new folder" was fixed in bug #171416; it's not a treeview bug. I'm thinking that the tree row for the new folder name should have an explicit "Create" button to the right of where you type, or we should go back to using a secondary dialog to ask the user for the folder's name. Summary: focus-out should not cancel the editing. Ignore the file chooser for now; it's a special case. See below for what I think is the right behavior. > Related question, what happens if you have a window with two tree views, and > both have editing active at the same time? You can't (shouldn't) be able to achieve that - that would mean two focused widgets in the same window. If you want to copy&paste from one treeview to another, you: 1. start editing the first treeview; select, copy. 2. start editing the second treeview; this finishes editing the first one. 3. paste in the second cell. I think the right behavior is this: * Focus-out commits the edit, in all cases. In addition... * ... if the input focus is lost to another (toplevel) window, and later the original window with the treeview regains the focus, then the treeview resumes editing where you left it, cursor and everything. This works well in Evolution's task pane, for example, and is totally what I expect. * Pressing Escape cancels editing. If you press the "Cancel" button on a dialog while editing, or if you close the window with the window manager's controls, I would expect the application to not commit the data since a dialog with a "Cancel" button means that the app knows not to commit the changes the user did. I.e. the app is smart enough to make the treeview operate on a temporary copy of the data, which is committed or not to the master data depending on how the dialog is closed.
> Summary: focus-out should not cancel the editing. Ignore the file chooser for > now; it's a special case. See below for what I think is the right behavior. > > > Related question, what happens if you have a window with two tree views, and > > both have editing active at the same time? > > I think the right behavior is this: > > * Focus-out commits the edit, in all cases. In addition... Even if we disregard what the file chooser is doing -- can there be more cases (perhaps in third-party code) in which you do not really want focus-out to commit the edit? The only things I can come up with are constructions similar to what the file chooser is doing and some construction with a "validating" entry in which invalid data is entered at the point focus-out will commit the edit. I am still wondering whether it makes sense to distinguish by commit due to focus-out and commit due to acceptance (pressed enter). Or perhaps even a "test-should-commit" signal so individual applications can choose for themselves ... Say they can put the data in some "temporary" buffer used in conjunction with your second point. > * ... if the input focus is lost to another (toplevel) window, and later the > original window with the treeview regains the focus, then the treeview resumes > editing where you left it, cursor and everything. This works well in > Evolution's task pane, for example, and is totally what I expect. I agree this would be very good to have. > * Pressing Escape cancels editing. If you press the "Cancel" button on a > dialog while editing, or if you close the window with the window manager's > controls, I would expect the application to not commit the data since a dialog > with a "Cancel" button means that the app knows not to commit the changes the > user did. I.e. the app is smart enough to make the treeview operate on a > temporary copy of the data, which is committed or not to the master data > depending on how the dialog is closed. Does this also work for: 0. Initial state. 1. I start editing. 2. Tree view loses focus because I am moving elsewhere (so tree view commits). 3. I copy something. 4. I go back to the tree view, tree view resumes editing. 5. I paste something. 6. I press Escape. To which point to we rollback? 2. or 0.? If 0., a temporary buffer might do it which could be implemented using commit-focus-out and commit-acceptance signals (of course they need proper names ;) which I argued above.
The problem seems to be related to input method! When I use iBus as input method, the problem occurrs! When I use gcin as the input method, the problem solves by itself.
(In reply to comment #9) > Even if we disregard what the file chooser is doing -- can there be more cases > (perhaps in third-party code) in which you do not really want focus-out to > commit the edit? [...] > I am still wondering whether it makes sense to distinguish by commit due to > focus-out and commit due to acceptance (pressed enter). Man, how vacations change one's perspective. I think the cleanest way to see this is by allowing the "editing" state to remain active while the widget is-focus, even if it is not has-focus: 1. If the treeview is the focus widget within its toplevel window, then editing remains active. 2. If the treeview loses the input focus because you move the mouse to another window, editing remains active and with all its temporary state (but the treeview is suitably drawn as unfocused, of course). 3. If the treeview loses the widget focus (e.g. you click on Ok), then editing is committed and stopped. 4. Editing is canceled only if you hit Escape. This would give us the behavior I described in the other comments. > Does this also work for: > > 0. Initial state. > 1. I start editing. > 2. Tree view loses focus because I am moving elsewhere (so tree view commits). > 3. I copy something. > 4. I go back to the tree view, tree view resumes editing. > 5. I paste something. > 6. I press Escape. > > To which point to we rollback? 2. or 0.? If 0., a temporary buffer might do > it which could be implemented using commit-focus-out and commit-acceptance > signals (of course they need proper names ;) which I argued above. We roll back to 0. This would happen automatically with my scheme above, since (2) wouldn't commit the data due to loss of input focus - editing would remain active as long as the treeview keeps the widget focus.
BTW, comment #11 doesn't address validation before committing. I'm not sure how to achieve it so that: 1. You start editing a validated cell. 2. You type garbage. 3. You click the OK button. In reality you don't want the OK button to work; instead you want the treeview to flame you. Maybe that is best left to the application anyway; they'll already have some machinery to validate things if needed.
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.