-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Core Rewrite [RFC] #553
Comments
Forgot to also ping @zeddo123 for comments :) |
I saw this, but forgot to look more closely and comment. I'm not an experienced architect or something. It's also currently midnight. GUII haven't really looked into TreeView and alternatives yet, but I think we should at least keep the tree display, since it shows the "relations". Looking at GTK4 it still has TreeView, but also a simplier list-based that is supposed to be more customizable, but need additional work to emulate tree views. If we are already talking about adaptive UI, we could also look into libhandy, but since I don't think it dramatically changes the code, I wouldn't consider it for this issue. LiblarchI'm not sure about merging liblarch into GTG. Inside GTGI agree about using signals more than callbacks. I don't really know what the requester and datastore exactly do, so I can't really comment on that. TagsI haven't really looked into yet, but separating tags from non-tags sounds good. About the tags, I think letting them have attributes is OK. I am also not sure about tags having children. I don't think it is used that often, but I am not sure if there are "valid" usecases for it to keep. ProposalSounds fine overall. From what I understand, serialization (and probably deserialization) would be done in the Lists themselves, which I am unsure about. I would definitively suggest moving "long-running" tasks to their thread so the UI is at least responsive, which is in my opinion important. RoadmapFor Phase 0, not sure about the Borg and requester stuff, since I don't know what it does/is for. In phase 5 I am worried a little about replacing it with listboxes. It would imply we need to do the tree stuff again (unless there is something premade). One thing is that they seem a bit ambitious. It seems a lot to do, and we need people not loosing interest too fast and not go "not too much time currently". Also, we need extensive testing, especially when we're switching to the new implementation (Primarily phase 6 from what I can see). |
No problem, thanks for commenting :D
Yep, that's the idea. We need to replicate the indent and showing/hiding but Gnome Todo and Planner already do this, so it is definitely doable.
Libhandy (soon to be libadwaita?) doesn't provide anything for trees, only listboxes: Paving the way to adaptive UIs is def part of this proposal though.
This isn't about merging liblarch, but rather replacing it with a simpler system. Liblarch could still live in its repo.
The datastore manages backends, while the requester is a neat API around it.
Not sure I understand what you meant here
I use this to organize tags in the sidebar (don't know if there are any extra features)
Yup, the datastore would do it.
I don't quite understand this part. There's always a localfile backend, so the xml is always read and saved.
Indeed. However this can run parallel to other things in GTG all the way to phase 5, so there's little risk. |
Sadly for the whole GUI part, as much as I've been tinkering with it and liblarch to try to get some performance improvements out of it, I am not at all knowledgeable on the matter (or on the current state of Gtk). I know that Gtk4 might be coming up but I'll trust you on that part.
As GTG is the sole project making use of
Although I did manage to work up some unittest on the caldav branch (very lite on the "unit" part) I'm agreeing with you. Testing shouldn't be the only purpose of that refactor but it's indeed needed.
All in all : 👍
In the same spirit I would also suggest to get rid of overriding For objects like I would be happy to participate in that refactor. Especially since some of the points in the roadmap sounds within my reach :) |
Nice, will add that to the roadmap too
Dude! Fantastic catch, we should definitely do that.
Welcome aboard :) |
Overall the goals sound nice (from a cursory reading), particularly if you can indeed do it in modular refactorings that "work" even standalone, so that:
I'm glad you have "Write unit tests" as a goal in every phase, as there definitely should be tests to cover extensively what you'll refactor! It wouldn't be fun to spend months of devhell depending on humans like me to retest everything and repeatedly reporting zombie issues each time. As for liblarch, I would feel more at ease if you can do your invasive technological changes to GTG and to liblarch while preserving the existence of liblarch as a library that GTG uses, even if it's tailored to GTG; presuming @ploum's principles in issue #286 still hold true in this future architecture of yours, I think a big part of why liblarch exists as a standalone core and why it may be best to refactor & tune it (rather than abandoning it) is that it keeps you "honest" technically... As Lionel said last year:
I fear that if we move away from liblarch, in X years someone is going to say "Oh gosh, everything is a big spaghetti inside GTG's core, we gotta split that out into a library or something!" (just like in organizations, there is always the back-and-forth between centralization and decentralization). Also, keeping it separate might (I presume) keep the GTG codebase more manageable for new/occasional contributors to GTG, and who knows, maybe projects like Planner could use liblarch too somehow (in a way liblarch could serve as bit as its own "libAdwaita") While GTG is currently the only project known to use liblarch, it also means you don't have to guarantee the availability of old functionality in liblarch and can instead tailor it to your exact vision, so in practice it's not too limiting on that front, no? Personally, I've often encountered the case where a task of mine blocks several others, so in an ideal world I'd love to have the ability for my tasks to have multiple parents, which is mostly a visual representation challenge (see issue #634). |
Yes! One of the big ideas behind the rewrite is to make it easier (or even possible) to unit test. The
This rewrite doesn't touch liblarch at all. I mentioned in the chat that being "technically honest" should be the normal throughout all of GTG and not just the core, and making architectural decisions to discipline ourselves is a bad idea. In any case we can develop the new core completely in parallel (as I've been doing), and test it with unit tests and the developer console before plugging it into the UI.
Ah man, Planner... that takes me back. I don't see how splitting things into a library solves spaghetti code, other than forcing you to rewrite the code. Which you can already do without splitting. I also don't see how this makes things more manageable for contributors, who would have to work back and forth with two different repos. Which parts of GTG are in liblarch, and which on GTG itself? It's not so simple. For instance, you still have GTG code sitting in liblarch: https://github.com/getting-things-gnome/liblarch/blob/master/liblarch/filters_bank.py
I'll reply in that issue so we don't crowd this one too much |
Updated the roadmap section with the current status and changes on phase 4. |
As a couple quick comments:
(feel free to poke me on IRC if there's follow-ups on these points here, as it's hard for me to notice and react to GH notifications) |
@leio Gah, I came to comment about something else and just saw your comment. Sorry I took so long to reply!
This could be interesting indeed. We had something like a gantt graph, in the calendar view plugin. Don't know how many widgets like we would really need though, something that looks like a calendar would be the most useful one I think
I already worked out some tests for that in #737 . And ranchester has a more advanced Gtk4 branch that includes those filters/sorters (https://github.com/ranchester2/gtg/tree/ng)
Yup, saw that when I studied the docs. I still think we should move away from trees and explore other options (Also added a mockup in #737 ) |
Now that backends are back, I've been reading up on the code and writing down a few ideas. Big question: Do backends need to be different from plugins?
Pinging @jaesivsm since I think you know the backends code better than anyone ATM |
0.4 brought the port to Gtk3, Python3, GtkApplication, GtkMainWindow, GActions and Meson.
0.5 is bringing Lxml, a new taskview and a new file format.
This ticket is the result of the notes I’ve been taking over many months, a bird's eye view and discussion of the next big refactor(s). This should start in 0.6 but will likely take a few releases to come together.
Also pinging: @Neui and @jaesivsm for comments
The targets for this are:
Comments, ideas, any feedback welcome!
Problems
GUI
TreeViews have fallen out of favor in most Gnome Apps since the days of Gtk2.
One of the problems with TreeViews is that their rendering method (cell renders) is different from regular widgets, which means they can’t use CSS or be animated. We are also severely constrained in the UI we can design for task/tag rows.
I’m also not very clear on how TreeViews fit with adaptive GUIs (which we may want to do at some point).
Finally we will eventually have to move away from Treeviews. At the very least for column views in Gtk4.
This was partially prophesied in the old GTG mockups: https://wiki.gnome.org/Apps/GTG/Design
Liblarch
According to @ploum:
Liblarch also includes support for multiple parents for a task (or node). The use case is subtasks that are blocked by more than one task. However, this could also be implemented by adding a “blocked_by” field and linking tasks by their IDs.
The biggest problem with liblarch is performance. Most of GTG performance issues can be traced back to liblarch, in particular the sorting and refiltering methods.
The second problem is maintainability. Liblarch adds a lot of code on our shoulders for the purpose of being a library, making TreeViews more convenient and supporting multiple parents per task. However:
GTG remains the only user of liblarch, and that’s unlikely to change (given where the general trend in UIs is going)
We and the general design of GNOME are moving away from Treeviews
We don’t use multiple parents (and have other possible solutions)
Inside GTG
Unit testing GTG is complicated because most classes are tightly coupled. Pretty much everything depends on the requester, and the requester depends on the datastore which initializes the backends and config system. So if you want to test a particular class you end up pulling everything.
We are also not properly using signals in Gtk, which leads to a lot of callback functions bouncing all over and tight coupling between classes.
Tags
Tags are designed to be created and deleted on the fly, but this conflicts with the idea of having persistent tag settings (color, icon, etc) as well as having children. This makes things like renaming rather hacky because the tag name acts as an ID, the tag being renamed has to be deleted and have its settings copied to a new one.
The sidebar is a single Treeview. “All Tasks”, “Tasks with no tags”, “Saved Searches” and even the separator line are implemented as special tags that get created on runtime abusing the attributes system (technically a dict).
Every method that deals with the list of tags has to make special exceptions for tags that have a “special” or “query” attribute.
Proposal
Move the models to
GListStore
s. Then create wrapper classes that will take care of manipulating the models, and de/serializing using lxml. Make a new class for Saved Searches (SavedSearch
) to separate them from tags. Simplify classes and their responsibilities to make unit testing easier. Use signals along with these changes to reduce coupling. Maybe even get rid of the requester eventually? (out of the scope for this)SavedSearch
Task
Tag
Tags, Tasks and Saved Search classes should only be responsible for themselves and have methods that manipulate their own data. That means no new subtasks from inside a task, no save methods on tags, etc.
New subtasks (for example) should be handled by the TaskList class, which takes care of inheriting tags/repeat/etc and then parenting the tasks.
Likewise, The *List classes should only deal with their own model and data.
The DataStore should be in charge of reading the xml files and passing the lxml elements into these classes so they can populate themselves.
Saving would work the other way around, *List classes would call a method to get an lxml element from a Task, Tag, etc. and gather them into their own root tags. All of those would be returned back to the DataStore which takes care of writing the xml with all those root elements (taskList, tagList, etc). With the new file format, everything is in one place so it makes sense to have only one save function. Saving can then be triggered by signals.
We should do some profiling to see if saving takes too long, and whether it’s worth writing it on a separate thread.
Roadmap
Each one of these steps is designed to be a small branch that can be tested and merged back into master somewhat quickly. This will also take more than one release, so this roadmap is designed to add the pieces gradually without affecting users and contributors.
This also means we can add smaller features and keep releasing while we work on this (and avoid dev hell). None of the phases can block a release, except phase 5.
Phase 0: Cleanup and Setup
Remove setters and getters that only have one line. Those that actually do something should use the@property
decoratorConvert the Requester class into a module. The requester is a class with no state, so it can be simplified into a module with functions and variables. This way all we have to do is import the requester and we don’t have to pass it around all the time(delayed until the other classes are in place)Move tag writing into local backendUse signals in the new Taskview(delayed: This could use some design, so we can use signals everywhere instead)Use__slots__
in Date classPhase 1: Saved Searches
Phase 2: Porting Tag
Phase 3: Porting Task
Phase 4: Read and save
Phase 5: GUI Improvements
This doesn’t include any big UI changes. New features could happen if they are easy enough to implement (or happen “naturally”).
Phase 6: Removing the old code
The text was updated successfully, but these errors were encountered: