-
Notifications
You must be signed in to change notification settings - Fork 22
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
Add wlr_output_manager support #62
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah, i’ve been wishing to implement this one for quite long now, thanks! ❤
As i’m not familiar with the protocol, this is more of a first-look review; hopefully i’ll manage to take the time and check also with the protocol (but by no chance should i be blocking merge).
Also, i’m only a contributor with no authority; what i say may be completely different from what buffet would say, so keep that in mind 😉
547d120
to
53b5eac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Just one omission and reviewing my own code 😂
Also feel free to mark any of the conversations as resolved; i don’t know why GitHub limits that to the PR author and repo owner.
fceb9a4
to
0acd10a
Compare
Can you split the diff unrelated to wlr_output_manager into a separate commit? It’s quite small i know, but it would help make the history cleaner. |
0acd10a
to
8efdb8d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my way to check it with the protocol :) (But i can’t promise i’ll have done it by tomorrow.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enjoy my thought train jumping back and forth 😇, i hope you can understand it.
Untested so far, only reviewed.
kiwmi/desktop/output.c
Outdated
if (okay && !test) { | ||
struct kiwmi_output *output = head->state.output->data; | ||
if (head->state.enabled) { | ||
if (output->enable_changed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol, i’m dumb. Of course would i focus on writing those mostly worthless nitpicks and forget that if enable_changed
, the output should be added to / removed from the output_layout
to match the behaviour of other compositors. (And, because we don’t want to send intermediate state, the output_layout_change
listener should be disabled / no-op while the configuration is in progress. Which also somewhat replies to #62 (comment).)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This one’s also resolved with the 2022-07-11 force-push; the parenthesised part lives on in another comment below.)
6db8601
to
d475202
Compare
Wait! No! This version isn't sending events to lua at all. Rats. I'll see if I can fix that tomorrow... |
d475202
to
d3f4100
Compare
Another small problem I've noticed: if you disable a monitor using wlr-randr or whatever, the bounds for the cursor remain unchanged; you can move it off screen, into the invisible place where that monitor used to be. I'm not sure why that's happening. When we create a wlr_cursor, we associate the wlr_output_layout with it, and wlroots registers its own handler for when that layout changes. I'll need to take a closer look at some point. |
I believe that’s related to #62 (comment): the |
d3f4100
to
782c945
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose i can keep nitpicking forever, oh well 🤦. The main logic seems good though!
This revision untested yet, as i’ve got a dirty tree that i’m lazy to clean atm, but your changes are okay. IIRC there was some issue before with sometimes erroneously getting a new output event, so i’ll see if it’s still there or got fixed mid-way (ignore it until i report back).
kiwmi/desktop/output.c
Outdated
void | ||
output_layout_change_notify(struct wl_listener *listener, void *UNUSED(data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this gets called also every time we modify the layout from within output_manager_configure()
. Possible ideas how to deal with it:
- have some state saying whether we’re in
output_manager_configure()
– if yes, return early- issue: existence of state similar to previous
kiwmi_output.enable_changed
- issue: existence of state similar to previous
- unregister the listener in
o_m_c()
, re-register at the end- issue: the listener will soon be used for other purposes (i use it in my PR as well)
- (variation of previous point) unregister the listener, re-register between the 2nd loop and the final
if
s; replace theset_configuration()
call with a manual emission of the event- issue: quite complicated
- keep it as it is and don’t fix what seems to work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also note that the config can misbehave and change the layout from within the callback, in which case it has to be updated before being sent to clients.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose i can keep nitpicking forever, oh well .
It's okay, I do have a talent for producing extremely nitpickable work
I've opted to just move the contents of that listener into a normal function that's called in the couple of places that it's needed. Nothing should be changing the output_layout outside of this file so it should work fine (correct me if I'm wrong). Seemed simpler than having a listener that doesn't actually correspond to the event it's listening to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing should be changing the output_layout outside of this file so it should work fine
The config can change it. And it seems pretty hard to me to get this right without removing kiwmi_output:move()
.
(so perhaps leave it be and add a todo? but were i the maintainer, i wouldn’t be happy merging such a thing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Humm, not only the config. If nested kiwmi is requested by its host compositor to resize, it also modifies the output layout without any direct action by us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot and I forgot that the config could move outputs.
I've added output_manager_update calls for both cases (changing the size of nested compositors sets off the mode change listener, so I've put that one in there). This does make things a little less neat though.
Given that your scene graph stuff also messes around with this, I'd suggest leaving it be for now, then once you've got your scene graph code finalised, you can make an informed decision on what's the neatest way of structuring it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that your scene graph stuff also messes around with this, I'd suggest leaving it be for now, then once you've got your scene graph code finalised, you can make an informed decision on what's the neatest way of structuring it.
Well, scratch that. Looks like I've got a rebase to do.
kiwmi/desktop/output.c
Outdated
struct kiwmi_output *output; | ||
wl_list_for_each (output, &desktop->outputs, link) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Self-note: should fix what’s iterated in my rebase (also if i rebase the scene PR onto this); then also the area!=NULL
check below makes sense.
output->wlr_output, | ||
head->state.x, | ||
head->state.y); | ||
wl_signal_emit(&output->events.resize, output); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This event is emitted even if the output isn’t resized. I think a check similar to enable_changed
would fix that. (Or should it be preserved so that all outputs emit some event?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The resize signal is now emitted if there are pending mode, scale or transform changes, or if head->state.x/y are different to the current values. Having moves trigger a resize event is a bit weird but I think the config should be told when an output moves and having seperate move and resize events doesn't seem worth the effort.
Seems like it got fixed and/or i remember wrongly. Edit: for the record, it’s only me being dumb again and testing my rebase rather than this PR. That wrong event was apparently caused by changes in wlroots 0.16. No need to worry for now; it can be solved when the time comes. |
The commit message also isn’t right anymore (fortunately):
|
This is basically some pre-emptive bug fixing before adding wlr_output_manager support in the next commit.
782c945
to
8916132
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems okayish, only the layout change propagation is more complicated.
kiwmi/desktop/output.c
Outdated
bool moved = output->wlr_output->pending.committed | ||
& (WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_SCALE | ||
| WLR_OUTPUT_STATE_TRANSFORM); | ||
struct wlr_output_layout_output *layout_output = | ||
wlr_output_layout_get( | ||
server->desktop.output_layout, output->wlr_output); | ||
moved |= head->state.x != layout_output->x | ||
|| head->state.y != layout_output->y; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn’t be scared of making this two variables, moved
& resized
. Would help code understanding and also make it easier to add a separate move
event to kiwmi_output
if desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair, though I'd recommend we keep moves and resizes in the same event, seeing as the vast majority of configs will be doing exactly the same thing in each case.
if (head == bad_head) { | ||
break; | ||
} else { | ||
continue; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My logic would be, if we’ve gotten here, continue
, instead of either break
, or continue
. Seems very subjective though.
if (head == bad_head) { | |
break; | |
} else { | |
continue; | |
} | |
if (head == bad_head) { | |
break; | |
} | |
continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's jumps on both outcomes of the if, I generally like to use if/else. Makes it clearer to me that the if statement is a for in the control flow rather than a detour that will rejoin.
I can change it if you'd prefer though.
This allows things like wlr-randr to work. wlr-randr or similar can send in two new events: `output_manager_apply' and `output_manager_test'. In output.c, their handler both call an new `output_manager_configure' function which loops through the list of outputs twice. The first loop applies all the requested configuration ad checks that its not all messed up. The second loop either commits that configuration or reverts it depending on whether it worked and whether we're responding to a test event. There's also now an output_manager_update function, called whenever the output layout is changed, which copies changes from the wlr_output_layout to the wlr_output_manager.
8916132
to
69507ee
Compare
This allows things like wlr-randr to work.
There's the standard wlroots plumbing to connect up, plus a few extra
checks here and there to make sure we're not trying to access an output
that doesn't exist anymore.