-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 Awesome/Monad style automatic layouts to Sway #1024
Conversation
- added L_AUTO_FIRST/LAST instead of using explicit layouts. - when switching between auto layout that don't share the same major axis, invert the width/height of their child views to preserve their relative proportions.
@@ -75,4 +75,7 @@ void swayc_log(log_importance_t verbosity, swayc_t *cont, const char* format, .. | |||
*/ | |||
enum swayc_layouts default_layout(swayc_t *output); | |||
|
|||
inline bool is_auto_layout(enum swayc_layouts 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.
Needs to be static inline
(GNU semantics).
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.
Needs to move out of the header and into a file (no code in headers, just don't make it inline)
@@ -10,6 +11,10 @@ irc.freenode.net). | |||
|
|||
[More screenshots](https://github.com/SirCmpwn/sway/wiki/Screenshots-of-Sway) | |||
|
|||
This fork attempts to add |
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 fork
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.
Yeah just revert all of the readme changes
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.
done
EXPECTED_EQUAL_TO, 2))) { | ||
return error; | ||
} | ||
int inc = (int) strtol(argv[1], NULL, 10); |
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 error handling for invalid ints here?
char *end;
int inc = (int)strtol(argv[1], &end, 10);
if (*end) {
// error
}
Also note no space between (int) and strtol
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.
done
enum swayc_layouts layout; | ||
if (strcasecmp(argv[1], "next") == 0) { | ||
if (is_auto_layout(parent->layout) && parent->layout < L_AUTO_LAST) { | ||
layout = parent->layout + 1; |
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 another function somewhere that uses a switch case or something, given a layout, to find the next auto layout? I'd rather not rely on the order of and value of the enum values.
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.
Nevermind, let's not
"Must be one of <prev|next>."); | ||
} | ||
swayc_change_layout(parent, layout); | ||
} else if (strcasecmp(argv[0], "promote") == 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.
Would prefer this as move promote
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.
renamed to "move first" (I actually had this change pending ... so I completely agree!)
*/ | ||
static int group_start_index(swayc_t *container, int index) { | ||
if ((index < 0) || (! is_auto_layout(container->layout)) || | ||
((uint_fast32_t) index < container->nb_master)) { |
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.
Weird indent here, also weird extra parenthesis
if (index < 0 || !is_auto_layout(container->layout)
|| (size_t)index < container->nb_master)) {
}
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.
trying out "spacemacs", haven't yet looked into having it format using tabs only. For now fixed it up manually.
return 0; | ||
} else { | ||
uint_fast32_t grp_sz = slave_count(container) / container->nb_slave_groups; | ||
uint_fast32_t remainder = slave_count(container) % container->nb_slave_groups; |
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.
Use size_t instead of uint_fast32_t
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.
done
return container->children->length; | ||
} else { | ||
int nxt_idx; | ||
if ((uint_fast32_t)index < container->nb_master) { |
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 goes for everywhere, s/uint_fast32_t/size_t/g
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.
done
* return the index of the Group containing <index>th child of <container>. | ||
* The index is the order of the group along the container's major axis (starting at 0). | ||
*/ | ||
static uint_fast32_t group_index(swayc_t *container, int index) { |
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 prefix all of these auto related functions with auto_?
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.
done
parent = container->parent; | ||
if ((parent->children && parent->children->length > 1) && | ||
(is_auto_layout(parent->layout) || (use_width ? parent->layout == L_HORIZ : | ||
parent->layout == L_VERT))) { |
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.
More weird indentation, use tabs
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.
fixed
return true; | ||
// Recursive resize does not handle positions, let arrange_windows | ||
// take care of that. | ||
arrange_windows(swayc_active_workspace(), -1, -1); |
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 whole function has now become pretty complicated. Can you split it up into several?
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 todo list...
// if layout change modifies the auto layout's major axis, swap width and height | ||
// to preserve current ratios. | ||
if (is_auto_layout(layout) && is_auto_layout(container->layout)) { | ||
enum swayc_layouts prev_major = (container->layout == L_AUTO_LEFT || |
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.
Unnecessary parens
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.
done
@@ -256,7 +260,7 @@ void move_container(swayc_t *container, enum movement_direction dir) { | |||
layout = L_VERT; | |||
} else if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { | |||
layout = L_HORIZ; | |||
} else { | |||
} else if (! (dir == MOVE_NEXT || dir == MOVE_PREV)) { |
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.
No space after !
@@ -279,19 +283,53 @@ void move_container(swayc_t *container, enum movement_direction dir) { | |||
sway_log(L_DEBUG, "container:%p, parent:%p, child %p,", | |||
container,parent,child); | |||
if (parent->layout == layout | |||
|| layout == L_NONE /* accept any layout for next/prev direction */ |
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 won't accept any layout, right? It'll accept no layout, which isn't a thing that happens in practice (things like views have no 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.
"layout == L_NONE" was to broad, replaced by "layout == L_NONE && parent->type == C_CONTAINER". This is intended to accept the MOVE_PREV/MOVE_NEXT directions regardless of the actual container layout.
static void apply_auto_layout(swayc_t *container, const double x, const double y, | ||
const double width, const double height, | ||
enum swayc_layouts group_layout, | ||
bool master_first); |
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.
Please make the indentation on these consistent
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.
attempted to make things more consistent (used tabs exclusively)
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.
grepped through the code for mixed tab/space indents and removed the ones I had put in.
|
||
switch(group_layout) { | ||
default: | ||
sway_log(L_ERROR, "Unknown layout type (%d) used in %s()", |
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.
Make this L_DEBUG. It's programmer error, right? Not user error? And is a recoverable condition?
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.
done
// height and width of next group to be laid out. | ||
const double *group_h, *group_w; | ||
|
||
switch(group_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.
Space after switch
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.
fixed
} | ||
|
||
/* update position for next group */ | ||
pos += group_dim; | ||
} | ||
} |
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 this function be split up a bit?
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.
definitely. on todo list.
Overall these changes look good. I like the refactored layout code. You should do a pass on this with the style guide in hand. There's a lot of complexity I would like to see simplified if you can spare the time to go through everything and see if you can find ways to simplify it (optional). These are some huge changes, so I'm not going to merge them right away. I'm going to start running them locally for a few days and see if they break any existing functionality. Would appreciate it if any Awesome users could try this and verify that it behaves appropriately as well. Could you make a wiki page explaining how to configure sway to behave like Awesome? |
Achieved by introducing auto_group_bounds function that produces the start/end indexes of a group inside an auto layot container.
- "layout auto_left|auto_xxx" are now "layout auto xxx" - "layout incmaster <n>" is now "layout auto master [set|inc] <n>" - "layout incncol <n>" is now "layout auto ncol [set|inc] <n>"
I've been playing around with swaygrab but haven't encountered any SEGVs. I'm stumped as to what caused the parent pointer to get mangled. I could poke around the core file (if you kept it) and it would be interesting if this is a/ reproducible and b/ what sequence of actions preceded the crash. As for the rest of the comments on the patch, I think I'm only missing the simplification bit (a few have been made, but nothing significant). Regarding reseting nb_master/nb_slave_groups when switching layouts, I would argue against since it's very convenient to switch back and forth to, say a tabbed layout, to use all the available space, and recover the child layout as it was prior to the switch. I also still need to push a sample Awesome-style config. |
Alright, I'll retest and rereview this when I have some time (probably today or tomorrow). I'll try to get some more info about the swaygrab issue as well (fwiw the failure was when trying to capture video). |
|
||
**layout** auto <mode>:: | ||
Sets layout to one of the auto modes, i.e. one of _left_, right_, _top_, | ||
or _bot_. |
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 spell out "bottom" 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.
done
@@ -360,7 +381,7 @@ The default colors are: | |||
switch to workspace 2, then invoke the "workspace 2" command again, you | |||
will be returned to workspace 1. Defaults to _no_. | |||
|
|||
**workspace_layout** <default|stacking|tabbed>:: | |||
**workspace_layout** <default|stacking|tabbed|auto_left|auto_right|auto_top|auto_bottom>:: |
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.
workspace_layout auto left
, not workspace_layout auto_left
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.
done
(Random side comment: instead of making i3 jump through hoops for KDE integration KDE should just behave better to not require special casing. Specifications exist for good reasons. I'm not sure why people don't consider this and then blame i3 for it.) |
Previous implementation would not preserve dimension of groups along the major axis. This should avoid weird behavior when using container motion commands.
Regarding thejan2009's comment, the most recent batch of commits should address the issue. When inserting/removing a child in a container, the auto-layout will attempt to preserve sizes along the "major" axis. Along the "minor" axis, sizes are preserved for children that aren't promoted/demoted to a different group. In the latter case their size will match the spot vacated in the arrival group. |
} | ||
bindsym $mod+r mode "resize" | ||
|
||
new_window pixel 1 |
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 put this into a directory called contrib
instead?
I would also make your sample awesome config more awesome like instead of trying to keep sway's default keybindings intact. Your config doesn't actually even include sway's default keybindings anyway, the defaults are via your config (rather than being hardcoded into sway). Fix that in a seperate pull request if you like. |
Thanks for all the hard work! |
You're welcome! Many thanks for yours on Sway and to the other contributors. |
Hi all,
I've been wanting to try out a Wayland setup and as an Awesome (and ex-i3) user, I gave Sway a spin. I quickly missed the (in my opinion) easy way with which Awesome just sorts out all the nitty-gritty of laying out your windows for you with a few simple pre-defined layouts that usually cover my limited needs. Anyway, long story short, I added the feature to Sway and find it quite pleasant to use. I took the opportunity to refactor some of the layout code. I'll probably add an includable config file to provide a setup that roughly matches Awesome's.
Enjoy!