Compare commits

...

4 commits

Author SHA1 Message Date
tokyo4j
24f39e3a41 default-bindings.h: set combine="yes" for SnapToEdge keybinds
Some checks failed
labwc.github.io / notify (push) Has been cancelled
2025-09-19 16:23:23 +09:00
tokyo4j
2ac48116e1 action: allow SnapToEdge to combine two cardinal directions
This patch adds `combine` argument to (Toggle)SnapToEdge actions.
This allows to snap a window to e.g. up-left by running two actions:
- `<action name="SnapToEdge" direction="left" combine="yes" />`
- `<action name="SnapToEdge" direction="up" combine="yes" />`

Then running `<action name="SnapToEdge" direction="down" combine="yes" />`
snaps it to left again. This behavior is almost the same as KWin, except
that snapping a up-right-tiled window to right doesn't move it to the
right-adjacent output, but makes it right-tiled first.
2025-09-19 16:23:23 +09:00
tokyo4j
af6a0df231 view: remove an obsolete code in view_snap_to_edge()
We no longer need to call view_apply_tiled_geometry() there, since we now
clear view->tiled when dragging a tiled window since 9f51384.
2025-09-19 16:23:23 +09:00
Johan Malm
0db3b9309b libsfdo.wrap: update revision to v0.1.4 2025-09-18 23:42:53 +02:00
9 changed files with 87 additions and 39 deletions

View file

@ -92,11 +92,18 @@ Actions are used in menus and keyboard/mouse bindings.
Move window relative to its current position. Positive value of x moves Move window relative to its current position. Positive value of x moves
it right, negative left. Positive value of y moves it down, negative up. it right, negative left. Positive value of y moves it down, negative up.
*<action name="ToggleSnapToEdge" direction="value" />*++ *<action name="ToggleSnapToEdge" direction="value" combine="value" />*++
*<action name="SnapToEdge" direction="value" />* *<action name="SnapToEdge" direction="value" combine="value" />*
Resize window to fill half the output in the given direction. Supports Resize window to fill half or quarter the output in the given direction.
directions "left", "up", "right", "down", "up-left", "up-right", "down-left",
"down-right" and "center". *direction* [up|down|left|right|up-left|up-right|down-left|down-right|center]
Direction in which to snap the window.
*combine* [yes|no]
Allows to snap a window to an output corner by combining two
directions. For example, snapping a window to *right* and then
to *up* places it in the *up-right* quarter of the output.
Default is no.
ToggleSnapToEdge additionally toggles the active window between ToggleSnapToEdge additionally toggles the active window between
tiled to the given direction and its untiled position. tiled to the given direction and its untiled position.

View file

@ -727,7 +727,7 @@ extending outward from the snapped edge.
W-Return - lab-sensible-terminal W-Return - lab-sensible-terminal
A-F4 - close window A-F4 - close window
W-a - toggle maximize W-a - toggle maximize
W-<arrow> - resize window to fill half the output W-<arrow> - resize window to fill half or quarter of the output
A-Space - show window menu A-Space - show window menu
``` ```

View file

@ -271,16 +271,16 @@
<action name="ToggleMaximize" /> <action name="ToggleMaximize" />
</keybind> </keybind>
<keybind key="W-Left"> <keybind key="W-Left">
<action name="SnapToEdge" direction="left" /> <action name="SnapToEdge" direction="left" combine="yes" />
</keybind> </keybind>
<keybind key="W-Right"> <keybind key="W-Right">
<action name="SnapToEdge" direction="right" /> <action name="SnapToEdge" direction="right" combine="yes" />
</keybind> </keybind>
<keybind key="W-Up"> <keybind key="W-Up">
<action name="SnapToEdge" direction="up" /> <action name="SnapToEdge" direction="up" combine="yes" />
</keybind> </keybind>
<keybind key="W-Down"> <keybind key="W-Down">
<action name="SnapToEdge" direction="down" /> <action name="SnapToEdge" direction="down" combine="yes" />
</keybind> </keybind>
<keybind key="A-Space"> <keybind key="A-Space">
<action name="ShowMenu" menu="client-menu" atCursor="no" /> <action name="ShowMenu" menu="client-menu" atCursor="no" />

View file

@ -35,6 +35,10 @@ static struct key_combos {
.name = "direction", .name = "direction",
.value = "left", .value = "left",
}, },
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, { }, {
.binding = "W-Right", .binding = "W-Right",
.action = "SnapToEdge", .action = "SnapToEdge",
@ -42,6 +46,10 @@ static struct key_combos {
.name = "direction", .name = "direction",
.value = "right", .value = "right",
}, },
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, { }, {
.binding = "W-Up", .binding = "W-Up",
.action = "SnapToEdge", .action = "SnapToEdge",
@ -49,6 +57,10 @@ static struct key_combos {
.name = "direction", .name = "direction",
.value = "up", .value = "up",
}, },
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, { }, {
.binding = "W-Down", .binding = "W-Down",
.action = "SnapToEdge", .action = "SnapToEdge",
@ -56,6 +68,10 @@ static struct key_combos {
.name = "direction", .name = "direction",
.value = "down", .value = "down",
}, },
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, { }, {
.binding = "A-Space", .binding = "A-Space",
.action = "ShowMenu", .action = "ShowMenu",

View file

@ -548,7 +548,7 @@ void view_move_to_edge(struct view *view, enum lab_edge direction, bool snap_to_
void view_grow_to_edge(struct view *view, enum lab_edge direction); void view_grow_to_edge(struct view *view, enum lab_edge direction);
void view_shrink_to_edge(struct view *view, enum lab_edge direction); void view_shrink_to_edge(struct view *view, enum lab_edge direction);
void view_snap_to_edge(struct view *view, enum lab_edge direction, void view_snap_to_edge(struct view *view, enum lab_edge direction,
bool across_outputs, bool store_natural_geometry); bool across_outputs, bool combine, bool store_natural_geometry);
void view_snap_to_region(struct view *view, struct region *region, bool store_natural_geometry); void view_snap_to_region(struct view *view, struct region *region, bool store_natural_geometry);
void view_move_to_output(struct view *view, struct output *output); void view_move_to_output(struct view *view, struct output *output);

View file

@ -337,11 +337,6 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
} }
break; break;
case ACTION_TYPE_MOVE_TO_EDGE: case ACTION_TYPE_MOVE_TO_EDGE:
if (!strcasecmp(argument, "snapWindows")) {
action_arg_add_bool(action, argument, parse_bool(content, true));
goto cleanup;
}
/* Falls through */
case ACTION_TYPE_TOGGLE_SNAP_TO_EDGE: case ACTION_TYPE_TOGGLE_SNAP_TO_EDGE:
case ACTION_TYPE_SNAP_TO_EDGE: case ACTION_TYPE_SNAP_TO_EDGE:
case ACTION_TYPE_GROW_TO_EDGE: case ACTION_TYPE_GROW_TO_EDGE:
@ -358,6 +353,17 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
} }
goto cleanup; goto cleanup;
} }
if (action->type == ACTION_TYPE_MOVE_TO_EDGE
&& !strcasecmp(argument, "snapWindows")) {
action_arg_add_bool(action, argument, parse_bool(content, true));
goto cleanup;
}
if ((action->type == ACTION_TYPE_SNAP_TO_EDGE
|| action->type == ACTION_TYPE_TOGGLE_SNAP_TO_EDGE)
&& !strcasecmp(argument, "combine")) {
action_arg_add_bool(action, argument, parse_bool(content, false));
goto cleanup;
}
break; break;
case ACTION_TYPE_SHOW_MENU: case ACTION_TYPE_SHOW_MENU:
if (!strcmp(argument, "menu")) { if (!strcmp(argument, "menu")) {
@ -1031,9 +1037,9 @@ run_action(struct view *view, struct server *server, struct action *action,
view_apply_natural_geometry(view); view_apply_natural_geometry(view);
break; break;
} }
view_snap_to_edge(view, edge, bool combine = action_get_bool(action, "combine", false);
/*across_outputs*/ true, view_snap_to_edge(view, edge, /*across_outputs*/ true,
/*store_natural_geometry*/ true); combine, /*store_natural_geometry*/ true);
} }
break; break;
case ACTION_TYPE_GROW_TO_EDGE: case ACTION_TYPE_GROW_TO_EDGE:

View file

@ -260,9 +260,8 @@ snap_to_edge(struct view *view)
view_maximize(view, VIEW_AXIS_BOTH, view_maximize(view, VIEW_AXIS_BOTH,
/*store_natural_geometry*/ false); /*store_natural_geometry*/ false);
} else { } else {
view_snap_to_edge(view, edge, view_snap_to_edge(view, edge, /*across_outputs*/ false,
/*across_outputs*/ false, /*combine*/ false, /*store_natural_geometry*/ false);
/*store_natural_geometry*/ false);
} }
return true; return true;

View file

@ -2126,7 +2126,7 @@ view_placement_parse(const char *policy)
void void
view_snap_to_edge(struct view *view, enum lab_edge edge, view_snap_to_edge(struct view *view, enum lab_edge edge,
bool across_outputs, bool store_natural_geometry) bool across_outputs, bool combine, bool store_natural_geometry)
{ {
assert(view); assert(view);
@ -2142,25 +2142,45 @@ view_snap_to_edge(struct view *view, enum lab_edge edge,
view_set_shade(view, false); view_set_shade(view, false);
if (across_outputs && view->tiled == edge && view->maximized == VIEW_AXIS_NONE) { if (lab_edge_is_cardinal(edge) && view->maximized == VIEW_AXIS_NONE) {
/* We are already tiled for this edge; try to switch outputs */ enum lab_edge invert_edge = lab_edge_invert(edge);
output = output_get_adjacent(view->output, edge, /* wrap */ false); /* Represents axis of snapping direction */
enum lab_edge parallel_mask = edge | invert_edge;
/*
* The vector view->tiled is split to components
* parallel/orthogonal to snapping direction. For example,
* view->tiled=TOP_LEFT is split to parallel_tiled=TOP and
* orthogonal_tiled=LEFT when edge=TOP or edge=BOTTOM.
*/
enum lab_edge parallel_tiled = view->tiled & parallel_mask;
enum lab_edge orthogonal_tiled = view->tiled & ~parallel_mask;
if (!output) { if (across_outputs && view->tiled == edge) {
/* /*
* No more output to move to * E.g. when window is tiled to up and being snapped
* * to up again, move it to the output above and tile
* We re-apply the tiled geometry without changing any * it to down.
* state because the window might have been moved away
* (and thus got untiled) and then snapped back to the
* original edge.
*/ */
view_apply_tiled_geometry(view); output = output_get_adjacent(view->output, edge,
return; /* wrap */ false);
if (!output) {
return;
}
edge = invert_edge;
} else if (combine && parallel_tiled == invert_edge
&& orthogonal_tiled != LAB_EDGE_NONE) {
/*
* E.g. when window is tiled to downleft/downright and
* being snapped to up, tile it to left/right.
*/
edge = view->tiled & ~parallel_mask;
} else if (combine && parallel_tiled == LAB_EDGE_NONE) {
/*
* E.g. when window is tiled to left/right and being
* snapped to up, tile it to upleft/upright.
*/
edge = view->tiled | edge;
} }
/* When switching outputs, jump to the opposite edge */
edge = lab_edge_invert(edge);
} }
if (view->maximized != VIEW_AXIS_NONE) { if (view->maximized != VIEW_AXIS_NONE) {

View file

@ -1,6 +1,6 @@
[wrap-git] [wrap-git]
url = https://gitlab.freedesktop.org/vyivel/libsfdo.git url = https://gitlab.freedesktop.org/vyivel/libsfdo.git
revision = v0.1.3 revision = v0.1.4
[provide] [provide]
dependency_names = libsfdo-basedir, libsfdo-desktop, libsfdo-icon dependency_names = libsfdo-basedir, libsfdo-desktop, libsfdo-icon