-
Notifications
You must be signed in to change notification settings - Fork 343
Add relative outputs to wlr_output_layout #1002
Conversation
I'm really not a fan of this. BUT I started to implement something in this general fashion for waymonad before, and dropped it because I couldn't find a statisfactory solution. There's a lot of things that can go wrong, and some tradeoffs have to be made in the end. I'd prefer if the |
@Ongy The idea was that using add_auto is fine for examples and just getting things on screen, but that it isn't really suited for compositors in general. See the discussion in #550 for the discussion on this. With that in mind I opted for the implementation that would require the least work. I prefer to see |
The latest response you got there is more on my line than yours here. But the As is, I'm against these changes. |
I'm not necessarily against having Regarding deadzones, while I do think it is useful to deal with them, I don't think cursor warping is something that should be in this PR, especially with the behavior of the previous paragraph. |
I always considerd the And yes, if they layout prevents detached outputs, the warping over deadzones won't be necessary at all. |
e4f8dc4
to
3b6da42
Compare
Reverted
Unless there's heavy opposition to this, I will make this into a separate issue. |
I'd like to keep the auto layout function as it is as I said in that issue because it's really useful for creating default layouts. |
It should behave the same in the last version of this PR |
types/wlr_output_layout.c
Outdated
@@ -190,6 +229,45 @@ static struct wlr_output_layout_output *output_layout_output_create( | |||
return l_output; | |||
} | |||
|
|||
// Adapted from wl_list_for_each | |||
// Starts with wlr_ to avoid name conflicts | |||
#define wlr_wl_list_for_each_offset(pos, head, member, offset) \ |
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'd rather write a little less efficient but more readable code
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.
Rather, I'm not quite sure why you define this here. It's only used once until the #undef, so it can just be inline.
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.
That's a remnant from when I used it in two functions
@@ -270,20 +348,6 @@ struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout, | |||
return NULL; | |||
} | |||
|
|||
void wlr_output_layout_move(struct wlr_output_layout *layout, | |||
struct wlr_output *output, int lx, int ly) { |
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.
don't remove this.
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.
wlr_output_layout_add
can do the same thing (and does so in master), so what would be the reason for keeping this around?
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.
It might make sense. Make an issue for it. It's an unrelated breaking public API change so it needs some discussion and visibility.
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 guess this might also depend on what is decided in #1013.
I'd rather just make the wlr_output_layout_output private. #1013 |
|
||
/** | ||
* Add an auto configured output to the layout relative to another output. | ||
* This will place the relative output next to the border of the absolute |
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.
s/absolute/reference/
* This will place the relative output next to the border of the absolute | ||
* output. The output layout will adjust dynamically to keep the relative | ||
* output in this position when the absolute output changes coordinates. | ||
* If either output is not in the output layout, it will be added. If the |
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.
it will be added
Hmm?
rootston/config.c
Outdated
free(lrc); | ||
} | ||
free(lc->name); | ||
free(kc); |
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.
kc
?
rootston/desktop.c
Outdated
desktop->layout = wlr_output_layout_create(); | ||
wlr_xdg_output_manager_create(server->wl_display, desktop->layout); | ||
struct roots_layout_config *default_layout; | ||
|
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.
Could add a little assert(!wl_list_empty(&config->layouts))
here
rootston/keyboard.c
Outdated
struct roots_layout_config *config = | ||
wl_container_of(next, desktop->layout->current_config, link); | ||
|
||
wlr_log(L_DEBUG, "Switching to layout %s", config->name); |
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'm not a fan of different output layouts for rootston.
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.
It's more of a development feature. It makes it easy to test multiple layouts without having to restart rootston and helps to test situations where the layout is changing.
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'm not a big fan of it but also not opposed to it, but either way it belongs in a separate PR imo
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.
Just this specific part of the rootston implementation or the whole rootston implementation?
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 multiple layouts and switching at runtime part
An output that is made relative to another output will appear on one of the borders of the parent output. Which border the outputs attaches to can be configured. An exception to this is the SAME_AS configuration. In this case child output is positioned at the same location as the parent output. When the parent output changes position, the child oututs will follow in order to maintain teh same relative position. Relative outputs may overlap depending on the configuration. While the original issue had detection of overlapping outputs as a feature, this better fits in the compositor, since the library would have to make assumptions about the wanted behavior. An implementation for rootston can be found in later commits. When an ouput is removed and is a parent of another output, the child output is fixed at its current position. If the compositor requires different behaviour it can do this in response to the destroy signal. Fixes swaywm#550
In order to properly manage relative layouts in rootston, the 'wlr_output_layout' has been encapsulated in 'roots_layout'. This is primarily to deal with outputs not being available to reference. This lives in rootston since compositors might want to deal differently with missing outputs. The behavior of rootston in the case of missing outputs, is to mark rules whose relative output is not available as unconfigured. When an output is unconfigured it will be placed to the right of any other outputs. This way, no gaps will occur in the layout, unless the user specifically configures them with fixed output.
620dcd7
to
77ad9ab
Compare
Removed multiple layouts in rootston. @acrisci seems like you have missed my comment: #1002 (comment) |
rootston/rootston.ini.example
Outdated
# Output position configuration | ||
[layout] | ||
# Put the output with name VGA-1 at (0,0) | ||
VGA-1 = fixed 0 0 |
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.
Possible to change this to 0,0
(one argument)?
types/wlr_output_layout.c
Outdated
case WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_FIXED: | ||
break; | ||
case WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_LEFT_OF: { | ||
struct wlr_box *ref_box = |
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 indentation is a bit weird here
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.
Ah, that's because of brackets? If you prefer, use case THING:;
. But indenting with two levels is just weird.
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'm not a fan of that indentation either, but I'll just move the ref_box declaration above the switch statement.
types/wlr_output_layout.c
Outdated
break; | ||
case WLR_OUTPUT_LAYOUT_OUTPUT_CONFIGURATION_RELATIVE_LEFT_OF: { | ||
struct wlr_box *ref_box = | ||
output_layout_output_get_box(l_output->reference); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
types/wlr_output_layout.c
Outdated
wl_container_of((child_output)->link.next, output, link)) { | ||
while (child_output->reference != parent_output) { | ||
if (parent_output == output) { | ||
goto move_outputs; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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 need to break out of two loops, hence the goto
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.
Ah, right
types/wlr_output_layout.c
Outdated
return; | ||
} | ||
|
||
for (child_output = wl_container_of((output)->link.next, output, 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.
Not a fan of this complicated loop
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.
Not sure how to do it with wl_list_for_each
, I need to skip to the output that's being moved. It could be possible, but I don't feel it is all that cleaner.
types/wlr_output_layout.c
Outdated
} | ||
|
||
move_outputs: | ||
ref->next->prev = child_output->link.prev; // A->prev = B |
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.
Ah, so that's the code ordering outputs in topological ordering. I bet you can rewrite those manual pointer manipulations with wl_list_remove
and wl_list_insert
.
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.
Yes I can, I was just being too perfectionistic w.r.t. the number of required operations.
types/wlr_output_layout.c
Outdated
} else { | ||
struct wlr_output_layout_output *l_output_rel; | ||
|
||
wl_list_for_each(l_output_rel, &layout->outputs, link) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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 looks pretty good.
X=fixed 0,0 instead of X=fixed 0 0
All issues are addressed. I added error handling to the config parsing of the layout to prevent rootston from segfaulting when a user created an invalid configuration. |
rootston/layout.c
Outdated
} | ||
} | ||
|
||
void roots_layout_reflow(struct roots_layout *layout) { |
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.
Sorry if this is obvious, but why is this required? I don't even understand what this functions does.
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.
It finds a position for the outputs that rootston can't configure (no configuration is available or the reference output is not connected) such that nog gaps accur in the layout. The first loop obtains the extents of the outputs that rootston was able to configure, the second loop moves the outputs to a proper position.
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.
You probably have already discussed about this, but why can't this happen in wlr_output_layout
?
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 idea was to make the auto
configuration not too complex and have it as a set it and forget type of configuration for examples and prototypes. Having a very specific behavior for these kind of outputs in wlr_output_layout
might be to prescriptive for how compositors should handle outputs when they cannot be fully configured. Moving this into the wlr_output_layout
would cater this specific case, but might not be sufficient for other compositors. As a minor point, it also shows how one can extend the wlr_output_layout
and allowed me to see where it could be improved. #1002 (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.
Can you add a comment explaining what this function does, since it's not obvious from its name?
rootston/rootston.ini.example
Outdated
VGA-1 = fixed 0,0 | ||
# Put the output with name VGA-2 to the left of the output with name VGA-1 | ||
VGA-2 = left-of VGA-1 | ||
# Other possibilities include : right-of, above, below, mirror |
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.
Typo: no space between "include" and the colon (:fr:)
types/wlr_output_layout.c
Outdated
@@ -48,6 +47,17 @@ struct wlr_output_layout *wlr_output_layout_create(void) { | |||
static void output_layout_output_destroy( | |||
struct wlr_output_layout_output *l_output) { | |||
wlr_signal_emit_safe(&l_output->events.destroy, l_output); | |||
|
|||
struct wlr_output_layout_output *l_output_rel; |
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 code is duplicated in two places. Maybe it can be split in a function?
types/wlr_output_layout.c
Outdated
|
||
if (max_x == INT_MIN) { |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
rootston/layout.c
Outdated
void roots_layout_reflow(struct roots_layout *layout) { | ||
int max_x = INT_MIN; | ||
int max_x_y = 0; | ||
bool configured; |
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 can be accessed when uninitialized. Also, this variable doesn't seem to be used outside the loop, so it can be moved inside.
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.
Nice work!
Closed because it is too complex for wlroots. This should live completely in the compositor or in a separate client. |
Introduces a way for compositors to create layouts with outputs that are relative to other outputs.
These relative outputs will update when the position or size of the reference ouput changes.
A rootston implementation is provided which
See #550.
API changes:
removed wlr_output_layout_movewlr_output_layout_add_auto: changed behavior, ouputs added through this function do not adjust dynamically anymore.cc @Ongy @Timidger