Featured image for Today's Dev #18

Today's Dev #18

November 30, 2024

Today was a good day for all the config code in budgie-daemon v2. In yesterday's Today's Dev, I discussed my plans for changing up a fair bit of this code to ensure that when we do not have a config or a matching group, we generate a new "active group" and make sure that gets flushed to disk (with the intent to not overwrite any other groups in the config of course). Excluding the code for updating the active DisplayGroup when performing DBus setter method calls, everything works and the config basically mirrors my hand-written TOML config. To accomplish it, I first set out to change the DisplayConfig, DisplayGrouping, and DisplayGroupOutputConfig structs into classes, with respective private or protected members and appropriate setters and getters (to ensure more predictable behavior that messing with the struct members directly). I no longer have utils for generating those structs from TOML values, but rather have class constructors that take in the const toml::value& and a method toToml for converting the class back into a toml::ordered_value. This helped with tidying up the config code in general. While I was at it, I moved them to using QString, QList, and QStringList types for various members. In our DisplayGroup, we now have a method that is called when we have no matching DisplayGroup for the current Wayland output management / heads state, createDisplayGroupForState. This method:
  1. Creates a new DisplayGroup
  2. Sets the name to an auto-generated name that is basically a comma-separated list of the output serials, then appended with (Auto Generated). For example: 0x32394658, 0x41505846 (Auto Generated)
  3. Sets the output serials to a QStringList of all of our head serials from the manager.
  4. Sets it as the preferred group
  5. Sets the primary output to the first output. This will almost certainly change in the future.
After this, it'll generate the DisplayGroupOutputConfig for each of the outputs and add those to the DisplayGroup. With this created group from the state, we set it as the active group then immediately call our new saveState which will create a config (or simply add to it if we already had one but no matched group) and write it to disk. I won't go into the implementation detail for that stuff, feel free to check the commit if you are interested. Instead, I'd rather just show you the config it generates 😀
[preferences]
automatic_attach_outputs_relative_position = "none"

[[group]]
name = "0x32394658, 0x41505846 (Auto Generated)"
preferred = true
output_serials = ["0x32394658", "0x41505846"]
primary_output = "0x32394658"

[[group.output]]
serial = "0x32394658"
width = 3840
height = 2160
refresh = 60000000
position = [0, 0]
scale = 1.0
rotation = 0
adaptive_sync = false
disabled = false

[[group.output]]
serial = "0x41505846"
width = 3840
height = 2160
refresh = 60000000
position = [3840, 0]
scale = 1.0
rotation = 0
adaptive_sync = false
disabled = false
There still some work I may need to do related to the positioning code, since it is defining the position for 0x41505846 as 3840 on x when in reality it is 0x32394658, but I am doubtful a "normal" user would get impacted by that since they have never exactly been using an old implementation of budgie-daemon v2 with an existing config before, and in all likelihood the positions would be correct on first boot without the config, and if they are not then that is something the user would fix via display configuration...and therefore the correct state would get dumped to the config. So I might be overthinking that issue. Either way, good progress on that today. Tomorrow I'll work on ensuring the active DisplayGroup state is updated when changes are performed over DBus, then crack on with the goals listed in yesterday's post.
Did you know?
You can follow me on Bluesky, Mastodon, or Threads!