durst-notification / durst

dunst written in Rust
6 stars 4 forks source link

Project goals & design #6

Open tsipinakis opened 4 years ago

tsipinakis commented 4 years ago

I don't think the reasons for rewriting dunst need a lot of thought, C is definitely not the right language and has caused a lot of headaches over the years (I have flashbacks to reviewing that markup parser @bebehei wrote... God knows what that must have been like writing it)

PS: If you want to join the project, we'd be happy to have you there.

I've been thinking of doing this for a while as well actually, but my version never made it past 'Hello World'. So I'd definitely like to help here and see how this evolves.


I took the initiative to open this as a tracking issue to track the current implementation goals until durst reaches feature parity with dunst.

Are we doing a 1:1 rewrite of dunst or will we look into improving the design? Apart from the language choice, I think dunst suffers from piling on too many hacks over years of configuration updates without a lot of thought.

I'll throw some improvement ideas to start off:

bebehei commented 4 years ago

I have flashbacks to reviewing that markup parser @bebehei wrote... God knows what that must have been like writing it

And it's stil not merged yet :see_no_evil: :joy: I wanted to automate everything.... Mhmmm. well. But hey, I've learnt cool things about coccinelle. I'm still subscribed there on the users mailing list. :grin:

Are we doing a 1:1 rewrite of dunst or will we look into improving the design?

We're not doing a 1:1 rewrite of dunst. We're splitting the good things from the bad things of dunst, "borrow" (I don't want to say steal :grinning:) the good things and enrich them with the better concepts.

Configuration: I've already opened numerous issues [...]

Oh yeah. That's one part we'll completely drop and won't provide any backwards compatibility. The dunst ini file is disastrous. Ini is just a 1-dimensional file format with groups.The command line arguments are awful (who the heck has thought, that I want to supply my config file via cli arguments!?!). Modern programming languages use dictionaries (or trees however you want to call it) and so I think it's the right thing to use a dictionary-based config file: YAML (I remember you've asked the question once to implement it in dunst, can't find it rn).

Also having the possibility to have proper rule naming schemes (having matchers and actions):....

[...]
    rules:
        ruleA:
            match:
                - appname: "NAME"
            action:
                - foreground: "green"
        ruleB:
            match:
                - appname: "NAME2"
            action:
                - foreground: "blue"

Customizability: There have been many issues opened on the dunst repo about requests to slightly tweak the layout in one place,

Oh yeah, those are getting more and more on dunst. But we haven't yet defined a path to go. We had thoughts about using HTML/CSS for the GUI stack once another time we thought just using plain cairo (like dunst does it). We haven't settled on this topic yet.

The only thing GUI-wise, we have settled: GUI is logically split from the core. So that it's easy to support X11 and wayland at the same time (@Stunkymonkey uses wayland, I'm still on X).

customisability with rules? Definitely! Every option is a rule!


Our current plan for durst:

  1. Finish the FDN DBus server:
    • Implement the org.freedesktop.Notifications API fully
    • Implement a Notification Object
    • Make the history waiting and displayed queue work together
  2. Add configuration file support
    • YAML
    • add rules support (no rules needed at the beginning)
  3. Vendoring steps (make it easy)
    • Provide proper build
    • Add dbus/systemd service files
    • add debug tools (like what other manager is currently running)
  4. docs docs docs
    • setup proper infrastructure (maybe RTD) to write docs
    • write user docs
    • implementation docs
    • website
    • screenshots!
    • examples!
    • FAQs
  5. CI testing infrastructure
    • add testing framework
    • add tests
    • evaluate coverage (?)
    • CI build
  6. durstctl
    • Implement easy structure
    • add simple commands
    • enhance later to query state and data
  7. Add GUI support
    • ... ?

At our start (IIRC beginning of march), we said, that we want to have a replacement, which works for our use case. It'll take some additional time and effort (we're willing to take) to make others regard it as a viable replacement.

bebehei commented 4 years ago

So, I forgot the most important thing.

So I'd definitely like to help here and see how this evolves.

Nice to have you on board! I'm not sure about your Rust skills, but as you can see, there are plenty of different jobs to do. Currently, I'm not familiar with Rust and have to learn it, too. But most of the jobs aren't really bound to Rust.

So, whenever you make your first PR, I'll invite you into the org.

Stunkymonkey commented 4 years ago

Initially one of my first goals was to implement the whole pipeline. Because I got a bit more experience in rust then @bebehei . Should I continue to do so? Because both of you are much more experienced with notifications.

bebehei commented 4 years ago

Well just continue. If something isn't clear, ask. There will be always another pair of eyes looking on your code, before it's getting merged. So you can consider yourself as safe. If you'll break the standard, someone will tell you. For the case, that nobody found the mistake prior to merging it, nobody will rip off your head :smiley: :hocho:

And yeah, I could continue. But I'm not just not familiar with Rust, I've got no skills in it currently. The output would be a solid zero. The goal for me is clearly to learn Rust first.

Are you afraid of making "wrong decisions"? You won't be immune to wrong decisions. Today, someone delivered a perfect Pull Request on the dunst repository. it was in itself complete. I could have pressed the merge button. The only thing: he implemented a string splitter function (see python's "a,b,c".split(',')). But this functionality is already in GLib and he can remove half of his code again.

I bet we all experience a similar situation, you probably have already. The only difference between you and me: I haven't. But I haven't tried at all.

So, please keep up the work and we'll support each other! :muscle:

fwsmit commented 3 years ago

I'll add my thoughts here based on the things I've seen in dunst.

Mulitple windows

Add the ability to draw multiple windows that can be modified independently. Ideally this would be done in such a way that it allows for all the things that you could do with multiple instances of durst.

Add include directive

As proposed in https://github.com/dunst-project/dunst/issues/796. As more features are added to durst, the configuration will become bigger and bigger. Someone might come up with a clever ruling scheme you might want to use or a nice theme. Using an include you can keep your main config file clean, while adding those things. From a quick duckduckgo search it seems like this isn't possible in plain yaml (source). I haven't worked that much with YAML, but from a first impression I'm not a big fan. To me there are too many features and weird syntax elements that make it confusing for new users. And the one feature that I would like to be there, isn't there. I have never used it, but libucl seems like it has all the features we need, while not being too complicated. It also has rust bindings.

Improve code hierarchy

Dunst currently has some bad patterns in the code structure. What I mean with this is that there should be some library-like files and some implementation files. The library files should not depend on the implementation files and should not include implementation-specific code. In dunst, an obvious 'libary' file should be queues.{c,h}. This could be written so that it doesn't have dependencies on other files. Configuration settings could be passed in those functions to change it for specific use. The advantages of this way of structuring the code are that there is less risk of dependency cycles and it's easier to test the core code separate from the rest.

Make running and testing easier

This is a bit personal, but I often have some sort of notification coming in while for example compiling dunst or writing some code and I have to kill that instance of dunst before I can go ahead and test. It may be useful to document some kind of testing setup with scripts that would make it easier for us all to test our code.

Single source of truth

As we've seen in dunst, it's hard to keep two different files have the same data. If you compare the default dunstrc with the defaults in code, you will find many differences. This means new users that don't have a config file will have to deal with the ugly defaults in code until they discover that they haven't copied the default config file yet. My proposed solution to fix this is to create some good defaults in code, so no config file is needed to make durst function. We should also create a separate program that imports these values and creates a config file from it.


Add GUI support

What do you mean exactly by this? A GUI for configuring durst?

HTML/CSS

I'm not convinced there are enough use cases for this to implement a HTML/CSS renderer in durst. I'm more a fan of making most configurations possible by only changing the config file and for those who want to create an entirely different layout, maybe make it easy to add a single file somewhere in durst that can change the entire or part of the drawing code.


On another note, since durst is marketed as a replacement for dunst on wayland systems, what are your thoughts continuing working on this project? There hasn't been much progress yet, so I'm wondering how much you want to work on it.

tsipinakis commented 3 years ago

Great to see some activity in this! I was starting to think it was dead.

On another note, since durst is marketed as a replacement for dunst on wayland systems, what are your thoughts continuing working on this project? There hasn't been much progress yet, so I'm wondering how much you want to work on it.

Wayland isn't the only reason for a rewrite, in fact, I'm pretty sure the wayland support is a consideration made after the fact. Dunst is death by a thousand papercuts IMO. Between an ini configuration file that has had hacks upon hacks made on it and being written in C which is a nightmare both to debug any non-trivial issues but also for any string handling operations (which dunst does a ton of).

On another note, @bebehei & others, whats your thoughts on rewriting dunst directly (and part by part) rather than starting from a clean slate? Rust has excellent C interop so it could be replaced part by part. It would save on rebuilding the reputation of the repo/waiting for it to be picked up by users.

bebehei commented 3 years ago

@tsipinakis I would be fine with rewriting dunst in rust inside the dunst project.

I've never thought about this. This had some personal reasons. I've switched from i3 to sway in December, so I don't see any personal gain in supporting legacy C/X11 infrastructure. And albeit I've got good overlook over the dunst source code, I assumed it will overwhelm the project.

But since you're openly thinking about it, I might rethink this. @Stunkymonkey @fwSmit What are your thoughts on this?

bebehei commented 3 years ago

Mulitple windows

Full ACK.

Add include directive

This is covered with a simple YAML anchor. Yes it's

I'm absolutely fine with ever format. YAML has its downsides ("no" and no being different types, etc..). But it's a standard and I don't have to teach others how to write it.

The docs are easy to write:

Syntax: It's YAML. We need such a structure defined in the config file: ....

And we only have to write down the structure, what we're actually using. Nothing more. There is no syntax to actually specify. Include, deduplication features are all in the syntax already included.

Make running and testing easier

:100:

Single source of truth

I don't fully get what you mean. Are you talking about the ability to specify (too many) options via cli and via config file (and while it's not specified, it's taken from the default structure)?


On another note, since durst is marketed as a replacement for dunst on wayland systems, what are your thoughts continuing working on this project? There hasn't been much progress yet, so I'm wondering how much you want to work on it.

I switched to NixOS end of 2018 or so and started to work full time in 2019, moved cities, full programme. The switch to NixOS diminished my contributions to dunst in some way, while the full time job then killed the rest.

Developing on NixOS has a steep learning curve. In hindsight, I have to admit I switched way too early. But now, I know how the stuff works, and I'm fully productive again on this system.

Now with the pandemic going on in Germany, I've got way too much time available again.

With the switch from C to Rust, it'll be the same like switching from Arch to NixOS. It'll be a steep learning curve and I don't expect to be productive at the beginning.

fwsmit commented 3 years ago

@tsipinakis I would be fine with rewriting dunst in rust inside the dunst project.

Yeah me too. I'm working on a settings refactoring for dunst, so I can try to write that in rust.

I've never thought about this. This had some personal reasons. I've switched from i3 to sway in December, so I don't see any personal gain in supporting legacy C/X11 infrastructure. And albeit I've got good overlook over the dunst source code, I assumed it will overwhelm the project.

But since you're openly thinking about it, I might rethink this. @Stunkymonkey @fwSmit What are your thoughts on this?

I think the X11 infrastructure is relatively separate from the rest. You can basically ignore it when writing other things. There is of course all the legacy C code, but I think it's OK to work with. As far as I can tell it's not possible to make a single binary from the rust and C code, but then we can just ship a library with dunst that contains the rust stuff (source).

fwsmit commented 3 years ago

I don't fully get what you mean. Are you talking about the ability to specify (too many) options via cli and via config file (and while it's not specified, it's taken from the default structure)?

I take this one partly back. You can ignore the example I gave here, but the idea still holds. When documenting things, make sure there is only one source and generate your documentation from that where possible.

Edit: One thing this could be used for in dunst is generate the part of the man page where the settings are explained from an array in code. When you add a setting, you can just add an entry in the array with an explanation what the setting does and you're done.

I switched to NixOS end of 2018 or so and started to work full time in 2019, moved cities, full programme. The switch to NixOS diminished my contributions to dunst in some way, while the full time job then killed the rest.

Developing on NixOS has a steep learning curve. In hindsight, I have to admit I switched way too early. But now, I know how the stuff works, and I'm fully productive again on this system.

Now with the pandemic going on in Germany, I've got way too much time available again.

With the switch from C to Rust, it'll be the same like switching from Arch to NixOS. It'll be a steep learning curve and I don't expect to be productive at the beginning.

Ah thanks for explaining :+1: .

tsipinakis commented 3 years ago

Yeah me too. I'm working on a settings refactoring for dunst, so I can try to write that in rust.

That'll work as a PoC on the rewrite but please refrain on submitting a PR just yet. I want to a) submit an issue on the dunst tracker about this, get some feedback there. and b) contact @knopwob. I believe he still gets veto rights here, even if he's been inactive that long :)

tsipinakis commented 3 years ago

One more thing to consider that I just thought of now: Rewriting means we, to some extent, have to keep backwards compatibility until we can dub it 'dunst 2.0' and drop all the built-up baggage of the ages. At this point it will essentially be a completely different project - with different configuration formats and (probably) different display options. And on top of that there's the effort of interfacing with the current code

So perhaps keeping it here would be more appropriate. I'm having mixed feelings about this.

knopwob commented 3 years ago

Dunst started as a weekend project to learn C. The biggest lesson I've learned while writing Dunst was "don't use C unless you have a very good reason!"

So I don't mind switching the language. I personally can't code in Rust but I don't see myself working on Dunst in the near or far future therefore I don't really have an opinion on that decision.

tsipinakis commented 3 years ago

Dunst started as a weekend project to learn C. The biggest lesson I've learned while writing Dunst was "don't use C unless you have a very good reason!"

Couldn't agree more. I guess that's one thing crossed off the list!

As far as I can tell it's not possible to make a single binary from the rust and C code, but then we can just ship a library with dunst that contains the rust stuff

We can link that library to the binary, no need to ship a separate file. See newsboat, a project I know that is in a similar process. Given, that case in a bit more complicated as it's C++, so they're doing a C++->C->Rust interface system which is quite messy.

Edit:

Rewriting means we, to some extent, have to keep backwards compatibility until we can dub it 'dunst 2.0' and drop all the built-up baggage of the ages

The other option here is to just have an 'unstable master' for a while and do a big backwards compatibility drop a long while later when we're ready to change things.

fwsmit commented 3 years ago

That'll work as a PoC on the rewrite but please refrain on submitting a PR just yet. I want to a) submit an issue on the dunst tracker about this, get some feedback there

The settings refactor should not change any behavior of how the settings work. It should only improve the code structure and the error messages. It implements the idea proposed in https://github.com/dunst-project/dunst/issues/412.

bebehei commented 3 years ago

Dunst started as a weekend project to learn C. The biggest lesson I've learned while writing Dunst was "don't use C unless you have a very good reason!"

Couldn't agree more. I guess that's one thing crossed off the list!

I've developed in dunst for the exact same reason. Let's misuse the project to learn a new language. I'm in! :100:

The settings refactor should not change any behavior of how the settings work. It should only improve the code structure and the error messages. It implements the idea proposed in dunst-project/dunst#412.

Well, I had a try there. And also I wanted to use it as a single source of truth, like you said. But in C, it turned out to be a whole preprocessor hell. Rust might be suited much better for it. Especially for documentation stuff.

The settings are a perfect type of moving it into a separate library!

fwsmit commented 3 years ago

I've developed in dunst for the exact same reason.

Yep me too :sweat_smile:

The settings are a perfect type of moving it into a separate library!

Yep, especially since you easily make mistakes with out of bounds access of arrays. I started implementing in C, because I have to use quite some structs and functions from other parts of the code. I didn't rewrite the reading of ini file. If we write the settings code in rust, it'll be easiest to rewrite the entire settings code.