Because writing your own layout system and management is just *so much
fun*. Totally.
-------------------------------------------------------------------
Moves the basic mode system over to the new drawing/widget system. In
the process, it has forced me to completely redo how we do layouts...
again. This is because basic mode has widgets that control their own
height - this means the height of the columns and rows that wrap it
are also affected by the widget's height.
The previous system, using a constraint tree and splitting draw Rects
via tui-rs' built-in constraint solver, did not support this concept
very well. It was not simple to propagate up the widths/heights
towards parents while also using tui-rs' built-in constraint solver.
In the end, it was easier to just rewrite it using another algorithm.
We now follow a process very similar to Flutter's layout system.
Relevant links to the Flutter docs are found in the code or below:
- https://flutter.dev/docs/development/ui/layout/constraints
- https://flutter.dev/docs/resources/inside-flutter#sublinear-layouts
The gist of it, however, is that we now instead a few new options for
any element in the layout tree. A node can either:
- Grow to fill remaining space
- Take up as much room as its children
- Be a specific length
Technically right now, it's not perfect, in that leaf nodes can be as
large as their children (which makes no sense), though in that case it
just treats it as an expand.
There were three bugs:
1. The click bounds calculation was incorrect. I did the silly mistake
of checking for <= bounds for the bottom and right sections of a
Rect when checking if the mouse intersected - this is WRONG.
For example, let's say you want to calculate if an x value of 5 falls
between something that starts at 0 and is 5 long. It shouldn't,
right? Because it draws from 0 to 4? But if you just did <=
Rect.right(), you would get a hit - because it just does (start +
width), so you get 5, and 5 <= 5!
So, easy fix, change all far bounds checks to <.
2. The second bug is a mistake where I accidentally did not include
bounds sets for my memory and net widgets. Instead, they set their
bounds to the underlying graph representation, which is WRONG, since
that bound gets updated on draw, and gets set to a slightly smaller
rect due to borders!
3. A slightly sneakier one. This broke my bounds checks for the CPU
widget - and it would have broken my process widget too.
The problem lies in the concept of widgets that handle multiple
"sub"-blocks internally, and how I was doing click detection
internally - I would check if the bounds of the internal Components
were hit. Say, the CPU, I would check if the internal graph was hit,
then if the internal table was hit.
But wait! I said in point 2 that a graph gets its borders updated on
draw to something slightly smaller, due to borders! And there's the
problem - it affected tables too. I was setting the bounds of
components to that of the *internal* representation - without borders
- but my click detection *needed* borders included!
Solution? Add another trait function to check bordered bounds, and
make the default implementation just check the existing bounds. For
cases like internal Components that may need it, I add a separate
implementation.
I also switched over all border bounds checks for Widgets to that,
since it's a bit more consistent.
Slightly move around the ideas of EventResult, ReturnSignalResult,
and how they all work.
The gist of it is that we now have widgets returning EventResults (and
renamed to WidgetEventResult), and the main app event handler returns
ReturnSignalResult (now named EventResult).
Also add a new signal to handle re-updating data inputs! This is needed
for the process, and any sortable/configurable widget.
This rips out this weird trait system I previously used for drawing
widgets, where I implemented a trait onto the Painter struct that did
the drawing. I have no idea what I was thinking back then.
Even more glue code to help glue together our layout options to our new
layout system!
Note that this PR will most likely likely break the two options:
- default_widget_type
- default_widget_count
and as such, they'll probably be deleted in a later commit.
As for why, it's since they're kinda a pain to support and don't work
well. Users can still enable default widget selection through the
layout system (which will also see a revamp in the future).
Adds a `ProductCode`, `Scope`, and `Commands` field to the template, as well as additional changes to the deploy process to determine + fill in the `ProductCode` automatically.
Swap to manually calculating the mem total and usage via procfs. The usage calculation is now:
total - (free + cached + buffers + slab_reclaimable - shmem)
This follows the same usage calculation as htop. See the PR for more details.
Fixes the accuracy of the memory widget for Linux and macOS, and uses binary prefixes instead to be more accurate.
Regarding the first part, it turns out that the way I was calculating memory usage was *slightly* incorrect for a few reasons:
- Regarding macOS, it seems like the way I was determining usage (`usage = total - available`) is not the most accurate. The better way of doing this is apparently `usage = wire + active`, where `wire` is memory always marked to stay in RAM, and `active` is memory currently in RAM. This seems to be much closer to other applications now.
- Regarding Linux, this was somewhat due to two issues - one was that I should have used heim's own built-in function call to get how much memory was *used*, and the other is that when heim reads info from `meminfo`, it reads it in *kilobytes* - however, the values are actually in *kibibytes*. As such, to get the value in kibibytes, you want to actually take it in kilobytes.
While I've filed an issue for the library, for now, I'll just manually bandaid over this. See https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-meminfo for more info.
Both changes take more advantage of platform-specific methods, and as such, the change unfortunately adds some ugly platform-specific code blocks.
Side note, Windows Task Manager apparently (?) uses binary prefixes for the values behind the scenes, but displays decimal prefixes. As such, now that we've switched to binary prefixes, it'll "seem" like the two aren't matching anymore since the units won't match, despite the values matching.
Adds the missing hide_time and battery config option to the default config and corresponding documentation.
Should probably automate the generation of this somehow tbh, though this might change when I add in-app config (soon™)
Seems like we have a few too many tests that aren't really needed for just asserting CI is passing.
The goal for CI (IMO) is just to ensure things still build on the various supported platforms after changes are made. However, there were a few tested scenarios like Windows GNU or musl which I feel weren't really too important in this regard, and added extra time to an already long CI process.
Commented out the following tests since there aren't any architecture-specific features that require running these in addition to other already-existing tests:
- Windows GNU
- Linux musl (both x86 and x86_64)
Of course, should we add changes that directly affect these architectures, then we should add the tests back.
Small refactor to remove the beef dependency for now.
This is likely just a tempoary change, I wanted to remove it just for clarity's sake among dependencies, and will probably add it back in the future.
For now I'll just stick to std's beef.
This is just a temp change, I wanted to remove it just for clarity's
sake among dependencies, and will probably add it back in the future.
For now I'll just stick to std's beef.