Skip to content
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

module(widgets): mass refactor, add system tray and battery #164

Merged
merged 10 commits into from
May 19, 2024

Conversation

pluiedev
Copy link
Contributor

@pluiedev pluiedev commented May 6, 2024

Fixes #126

Here's a list of changes:

  • Most of the code that generates the JS required for adding and configuring the widgets are now moved to modules/widgets/lib.nix. Since system trays are also technically containments, and configuring things there is very similar to configuring a panel, it's worth refactoring it into code that can be shared for both.

  • Every panel is now in its own scope, in order to avoid name collisions. As a direct consequence of that, all vars are replaced by consts, as there's now no need for redeclaring variables. Besides, var is a code smell anyways in modern JS due to its unpredictable scoping rules, and it's best to avoid it in new code.

  • Config fields in the same group of the same widget will now share the w.currentConfigGroup and w variable assignments. Essentially, instead of this:

    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Appearance"];
    w.writeConfig("title", "CPU Usage");
    
    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("highPrioritySensorIds", '["cpu/all/usage"]');
    
    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("lowPrioritySensorIds", '["cpu/all/temperature"]');
    
    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("totalSensors", '["cpu/all/usage"]');

    We now generate:

    const w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Appearance"];
    w.writeConfig("title", "CPU Usage");
    
    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("highPrioritySensorIds", "[\"cpu/all/usage\""]);
    w.writeConfig("lowPrioritySensorIds", "[\"cpu/all/temperature\""]);
    w.writeConfig("totalSensors", "[\"cpu/all/usage\"]");

    This massively cuts down generated code, and is much cleaner in general.

  • Every setting on every widget is now nullable. Setting anything to null basically makes it unset, which allows us to eliminate setting a default on the Nix side, so that upstream default changes won't affect us.

  • An extraConfig field has been added for raw widgets, that takes a lambda/anonymous function that accepts one argument — the widget to be configured. I figure this allows more room for the user to name the widget whatever they want, and not rely on hardcoded variable names.

    This is required to make system trays work, because configuring them is... quite peculiar, to say the least.

  • I've added a link to the config/main.xml file that defines each widget's config options, which is a much more reliable source than KDE docs.

  • The widget system now makes use of native module system features (such as the apply field for mkOption), in order to make converters less of an eyesore, make Nix report better errors, and make the system more robust against erroneous user input in general.

  • And of course, you can now customize system trays to your liking, without knowing what eldritch horror lies beneath to make it work.

  • Also, battery indicators!

Lots of changes:
- Most of the code that generates the JS required for adding and
  configuring the widgets are now moved to modules/widgets/lib.nix.
  Since system trays are also technically containments, and configuring
  things there is very similar to configuring a panel, it's worth
  refactoring it into code that can be shared for both.

- Every panel is now in its own scope, in order to avoid name
  collisions. And `var` in modern JavaScript just stinks anyway.

- Config fields in the same group of the same widget will now share the
  `w.currentConfigGroup` and `w` variable assignments. Essentially,
  instead of this:
  ```js
    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Appearance"];
    w.writeConfig("title", "CPU Usage");

    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("highPrioritySensorIds", "[\"cpu/all/usage\"]");

    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("lowPrioritySensorIds", "[\"cpu/all/temperature\"]");

    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("totalSensors", "[\"cpu/all/usage\"]");
  ```
  We now generate:
  ```js
    var w = panelWidgets["org.kde.plasma.systemmonitor"];
    w.currentConfigGroup = ["Appearance"];
    w.writeConfig("title", "CPU Usage");

    w.currentConfigGroup = ["Sensors"];
    w.writeConfig("highPrioritySensorIds", "[\"cpu/all/usage\""]);
    w.writeConfig("lowPrioritySensorIds", "[\"cpu/all/temperature\""]);
    w.writeConfig("totalSensors", "[\"cpu/all/usage\"]");
  ```
  This *massively* cuts down generated code, and is much cleaner in
  general.

- Every setting on every widget is now nullable. Setting anything to
  null basically makes it unset, which allows us to eliminate setting a
  default on the Nix side, so that upstream default changes won't affect
  us.

- An `extraConfig` field has been added for raw widgets, that takes a
  lambda/anonymous function that accepts one argument — the widget to be
  configured. I figure this allows more room for the user to name the
  widget whatever they want, and not rely on hardcoded variable names.
  This is *required* to make system trays work, because configuring them
  is... quite peculiar, to say the least.

- I've added a link to the config/main.xml file that defines each
  widget's config options, which is a much more reliable source than KDE
  docs.

- And of course, you can now customize system trays to your liking,
  without knowing what eldritch horror lies beneath to make it work.
@pluiedev pluiedev force-pushed the feat/systray-and-battery branch 2 times, most recently from 4ffefda to ea3e9f1 Compare May 6, 2024 22:12
@pluiedev pluiedev marked this pull request as draft May 7, 2024 18:07
@pluiedev
Copy link
Contributor Author

pluiedev commented May 7, 2024

I also realized that users would be able to do something patently stupid like:

{
  widgets = [
    {
      systemTray.items.configs = {
        systemTray.items.configs = {
          systemTray.items.configs = {
            battery.showPercentage = true;
          };
        };
      };
    }
  ];
}

Should you do this? No. Should you be able to do this? Yes.

@pluiedev pluiedev changed the title module(widgets): add system tray and battery module(widgets): mass refactor, add system tray and battery May 7, 2024
Possibly the simplest widget by far
Someone recently showed me that there's an `apply` setting for mkOption
that automagically does the type conversions that we've done manually so
far. This is great news as it cut down redundant code massively, and
we're able to extract common patterns like enums into the widgets lib.

I also reworked system tray's item configs to let it use the option
system to fill in the defaults *as specified* by the options. This
allows us to remove a lot of duplicate handling code that are designed
to fill in sensible defaults even when it's not been processed by the
option system.

Converters are frankly *much* easier to understand now, which is always a
good thing in my book.
Honestly I don't even know why JS allows you to call constructors
without parentheses, nor do I know why it's like that in the examples.
Anyway, we follow modern JS now, which means always using parens when
calling constructors
@pluiedev pluiedev marked this pull request as ready for review May 7, 2024 21:36
@magnouvean
Copy link
Collaborator

Nice. It's quite a big pr, but hopefully I can test it this weekend.

@magnouvean
Copy link
Collaborator

Works great as usual :). Will merge when checks are done. Thanks a lot once again!

@magnouvean magnouvean merged commit 5db76cb into pjones:trunk May 19, 2024
1 check passed
@lgoette
Copy link

lgoette commented May 31, 2024

Hey, thanks for the contribution. Works great :D
Is it possible to set popupHeight and popupWidth of the systemtray? I did not find options for these settings.

@pluiedev
Copy link
Contributor Author

Hey, thanks for the contribution. Works great :D Is it possible to set popupHeight and popupWidth of the systemtray? I did not find options for these settings.

Give it a try - it might not work 'cause I didn't set the freeformType, though

@lgoette
Copy link

lgoette commented Jun 1, 2024

I am not that familiar with how this works, sorry. But while iconSpacing etc is set in the [Containments][systrayID][General] location, popupHeight is set in the [Containments][systrayID] location. Is there an option to access this part of the config?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for custom containments / system tray
3 participants