gtg
gtg copied to clipboard
Partial tags duplication into gtg_data.xml when typing tags at various speeds in the Task Editor's TaskView
This is the remainder/successor to issue #557. Essentially, when you type tags "slowly enough for parsing to happen mid-way" in the task editor, especially if you type "back and forth" (ex.: type a partial word, wait, type some more, wait, type too much, wait, backspace a couple of characters, wait and then close the task editor), then you will encounter "intermediate" tags that are not used in the final saved tasks, but are saved as orphan tags in the gtg_data.xml file format:
Or another example from the last comment of https://github.com/getting-things-gnome/gtg/issues/557#issuecomment-788102087 :
Fixing this is not super trivial as, according to @diegogangl:
It gets more convoluted because tags are sometimes tags, and sometimes strings; there's the special tags, but saved searches are also tags and "special" as their parent is "search", but they are not really considered special in the code though
What are "special" tags if they are not searches? "All tasks", "Tasks with no tags", and... "separator"!
Solving this might depend on some refactoring (and ideally, tests!), so at this point this is probably 0.6 material rather than something to be fixed while on the verge of releasing 0.5.
@gycsaba96's #1062 tried to fix this, but the fix kind of "mostly changed the behavior" rather than only fixing the original issue. There are some new issues (arguably regressions) from that change:
- Whenever there is no space after a tag, it will no longer recognize it as a tag, and it will immediately remove it
- Empty tags can still get created and saved; while they immediately get removed from the sidebar, they get saved to the XML data file and will reappear on startup, i.e. the reverse of #1007...
Demonstration video with current git master
, where you can see several unexpected behaviors if you look closely:
Whenever there is no space after a tag, it will no longer recognize it as a tag, and it will immediately remove it
When you remove the space, it is indeed not parsed but only temporarily. Currently, the code assumes that changes happening inside or at the boundaries of the word mean that the user is editing that particular word. However, it does get saved when you make a change somewhere else or close the window.
Empty tags can still get created and saved; while they immediately get removed from the sidebar, they get saved to the XML data file and will reappear on startup, i.e. the reverse of Tags with zero issues are not shown on startup, but get shown after switching "Actionable" and "Open" view modes #1007...
I understand your point. This one is a tricky question.
Suppose the user is writing the contents of the task. Inside the text, a new @mylifedependsonit
tag is added. At this point, the program needs to recognize and save it. Otherwise, how could the user change the tag's color or make it a child of an existing tag (while still editing the task)? If the user erases the tag from the task later, they still did create a tag, even if it becomes empty, and having empty tags is a feature according to #560. It feels like a different "how to manage empty tasks?" question that is not directly related to the slow typing described at the beginning of the issue.
I'm not very familiar with the details, so this is just a broad idea, but I'm thinking that maybe a way to address this current (and the previous) issue is to go with a sort of "hybrid approach" that temporarily decouples the UI changes propagation vs the backend "file format writing" change committing.
Maybe something like this, conceptually:
- A 300-500ms timeout "after the user stopped typing" to "update the task editor's GUI", separately/before the changes get propagated to the rest of the UI (ex: sidebar, syntax highlighting in the task editor, etc.). In other words, "simulate" realtime parsing, maintaining the "It parses in realtime?! What is this sorcery?" illusion :)
- A longer combo of events that can trigger the propagation to the backend (and writing to the XML file), that is "whichever of these events/conditions occur first":
- A "word break" happened with a line break or a space (part of your current implementation)
- The Task Editor instance window was closed (part of your current implementation)
- The Task Editor instance window lost focus (ex: the user clicked on something else in the GUI, such as the main window or some other task editor instance); surely there is an event signal for that?
- When none of the above happened, i.e. the user has not defocused nor closed the window and has not added a space or linebreak after a tag: based on a 5 seconds timeout after the user stopped typing…
because we could consider that 5 seconds is quite unlikely to create duplicate/incomplete tags at all, as the user has had a fair amount of time to notice and correct any mistake? Note that this is for the backend/saving; the task editor's syntax highlighting thing would still be based on the other 300-500ms timer (which would be, in practice, kind of a faking trick)- If the save timeout delay is long, it could maybe even show an "Autosaved" in-headerbar-notification Google-Docs-style (or maybe a temporary in-app-notification overlay in the task editor window, like some other GNOME apps) when that happens, which could be reassuring to new users who are not used to autosaving (c.c. @TheEvilSkeleton ;)
- If we want to be ultra-consistent, we could make it so that the sidebar updates only when the above conditions are met (close/defocus or 5s timeout), potentially even showing a nice animation when "committing" the new tag additions to the sidebar...
I think the "commit when the instance's window loses focus" would prevent concurrency problems like what you described, no?
Am I forgetting something? Well, maybe the notion of deduplication of tags that were temporarily created within a new task but removed before closing the task, but that gets hairy and I suspect that with the ideas above (focus-out + 5 seconds special auto-save timeout) we would have so much less duplicates that even if one or two "leftovers" appear in the sidebar, the user will be able to manage them, I guess.
Thank you, @nekohayo , for the detailed description. I have carefully read it, and there are some points where I would like to ask for your further input.
- A "word break" happened with a line break or a space (part of your current implementation)
- The Task Editor instance window was closed (part of your current implementation)
Something doesn't add up for me. Could you please clarify the user story where the current solution results in an unwanted tag and the proposed one does not? (In the video, there was always a "word break", or the window was closed.)
- The Task Editor instance window lost focus (ex: the user clicked on something else in the GUI, such as the main window or some other task editor instance); surely there is an event signal for that?
This could be a nice enhancement so that you don't have to care so much about word breaks. (Maybe we could even add some explicit save key combinations.)
- When none of the above happened, i.e. the user has not defocused nor closed the window and has not added a space or linebreak after a tag: based on a 5 seconds timeout after the user stopped typing… because we could consider that 5 seconds is quite unlikely to create duplicate/incomplete tags at all, as the user has had a fair amount of time to notice and correct any mistake? Note that this is for the backend/saving; the task editor's syntax highlighting thing would still be based on the other 300-500ms timer (which would be, in practice, kind of a faking trick)
This sounds convincing. However, it would raise some accessibility issues. Suppose the user (who may experience challenges typing quickly) is misstyping a tag. Luckily, they haven't placed a "word break" or changed focus. Would that ticking 5s be enough for sure? It sounds like a frustrating situation. Currently, the user has as much time as they want, given that they don't start to edit somewhere else.