Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Atomic layout updates #2072
This is a very early concept/WIP of atomic layout updates. It's so early that my code won't even compile. You should consider it a proposal with some example code attached. I'm submitting it here so everyone can see the direction I'm going in and give feedback as the feature is developed.
The new data structures I'm proposing are:
The basic idea here is that when we want to arrange layout, we create a
Each instruction has a pointer to a container, a pending state which it'll apply to the container, and the configure serial.
I was originally going to have a
When arranging layout, it builds the new pending state from the container's existing pending state. This is so a second transaction running at the same time won't revert what the first transaction is trying to change. This means if no transactions are in progress, every container's pending state must be an accurate reflection of the current state.
As for how windows are arranged by commands and so on, if you only want to do one arrange, you'll be able to call
You may notice this means there's only two entry points for the arrange functions, rather than one for each container type as we had before.
I've updated the PR so it's now a basic working implementation. Atomic updates are implemented for the
The PR is ready to stash the last good surface texture away, but we need to have a good discussion on whether that's actually what we want to do, because apparently reading textures back from the GPU is expensive. So in lieu of a solution, if the transaction stalls for a view then you'll see the other surfaces resize before their borders and everything else does.
Ideas mentioned in chat for preserving textures are:
Anyway, when you resize a split, here's what's happening:
A good test is to change the
Then open an xdg_shell terminal, use that terminal to launch hello-wayland, then use the
Moving forward from here:
This seems pretty hard, there's no direct way to do it. We could:
I'd rather "steal" the texture from the
The pixel data is in the GPU, so it's tricky to just read it.
I'm making good progress on this.
I decided to make it so the main swayc/view properties are the pending state rather than the current state. This is because so much of the code works with these properties, and they need to work with the pending state. The only exception is rendering code which works with the current state. So the good news is everyone can continue to use
BTW, I consider the main/pending properties to be the "live" state, and the current state to be what the renderer displays which might be a few frames behind. So IPC events are sent when the live/pending state is changed.
I discovered we called the
I've made floating, fullscreen, and floating + fullscreen all work with transactions.
What's left now is:
This is now ready for testing. I'm going to start using this as my daily driver.
My latest commit implements atomic layouts for containers that are mapping, reparenting or unmapping.
How it works is we still have the regular tree, but the properties you're currently familiar with may not reflect what is actually rendered. Each container has a
Another key point is that destroying containers is now split into two steps: destroying and freeing. Destroying removes it from the tree (but keeps it in the
For views that are unmapping and destroying, a similar system is used. An unmapped view will still contain a reference to its swayc until it's no longer in a transaction. For this reason we can't use
To test what happens during a transaction, you can set
If you use
Possible issues or other points of discussion:
Works well, haven't found faults yet. One thing is that when toggling fullscreen any clients using the layer shell don't get damaged until they flip, but I'm guessing this would be fixed by proper layer shell client management (which would fix other bugs too probably, such as the damage from layer shell clients not affecting fullscreen clients).
After discussion on IRC, @RyanDwyer convinced me the destroy/free wording is a good idea.
Ehh. This code is sending an event with an uninitialized value. This code also bypasses all
In this case we don't want to send a frame event.