Added "Spring effect" when trying to swipe past limits

This commit is contained in:
Erik Reider 2024-01-22 14:41:29 +01:00
parent 29c481da95
commit fdf764d3f6
4 changed files with 57 additions and 4 deletions

View file

@ -71,10 +71,16 @@ struct sway_workspace *workspace_by_name(const char*);
struct sway_workspace *workspace_output_next(struct sway_workspace *current);
struct sway_workspace *workspace_output_next_wrap(struct sway_workspace *current,
bool should_wrap);
struct sway_workspace *workspace_next(struct sway_workspace *current);
struct sway_workspace *workspace_output_prev(struct sway_workspace *current);
struct sway_workspace *workspace_output_prev_wrap(struct sway_workspace *current,
bool should_wrap);
struct sway_workspace *workspace_prev(struct sway_workspace *current);
bool workspace_is_visible(struct sway_workspace *ws);

View file

@ -1128,16 +1128,25 @@ void update_workspace_scroll_percent(struct sway_seat *seat, int dx, int invert)
return;
}
// TODO: Make the threshold configurable??
const float THRESHOLD = MAX(0.35 - 0.1, 0);
// TODO: Make configurable?
// Visualized to the user that this is the last / first workspace by
// allowing a small swipe, a "Spring effect"
float spring_limit = (float) 50 / output->width * output->wlr_output->scale;
// Make sure that the limit is always smaller than the threshold
spring_limit = MIN(THRESHOLD, spring_limit);
// Limit the percent depending on if the workspace is the first/last or in
// the middle somewhere.
float min = -1.0f, max = 1.0f;
if (visible_index + 1 >= output->workspaces->length) {
// NOTE: Can be adjusted in the future to wrap around workspaces
max = 0;
max = spring_limit;
}
if (visible_index == 0) {
// NOTE: Can be adjusted in the future to wrap around workspaces
min = 0;
min = -spring_limit;
}
output->workspace_scroll_percent = MIN(max, MAX(min, percent));

View file

@ -2027,9 +2027,9 @@ void output_render(struct sway_output *output, struct timespec *when,
// Get the sibling workspaces
struct sway_workspace *other_ws = NULL;
if (output->workspace_scroll_percent < 0) {
other_ws = workspace_output_prev(workspace);
other_ws = workspace_output_prev_wrap(workspace, false);
} else {
other_ws = workspace_output_next(workspace);
other_ws = workspace_output_next_wrap(workspace, false);
}
struct sway_container *fullscreen_con = root->fullscreen_global;

View file

@ -555,6 +555,44 @@ struct sway_workspace *workspace_output_prev(struct sway_workspace *current) {
return workspace_output_prev_next_impl(current->output, -1);
}
/**
* Get the previous or next workspace on the specified output. Doesn't wrap
* around at the end and beginning. If next is false, the previous workspace
* is returned, otherwise the next one is returned.
*/
static struct sway_workspace *workspace_output_prev_next_no_wrap_impl(
struct sway_output *output, int dir) {
struct sway_seat *seat = input_manager_current_seat();
struct sway_workspace *workspace = seat_get_focused_workspace(seat);
if (!workspace) {
sway_log(SWAY_DEBUG,
"No focused workspace to base prev/next on output off of");
return NULL;
}
int index = list_find(output->workspaces, workspace) + dir;
if (index < 0 || index >= output->workspaces->length) {
return NULL;
}
return output->workspaces->items[index];
}
struct sway_workspace *workspace_output_next_wrap(struct sway_workspace *current,
bool should_wrap) {
if (should_wrap) {
return workspace_output_prev_next_impl(current->output, 1);
}
return workspace_output_prev_next_no_wrap_impl(current->output, 1);
}
struct sway_workspace *workspace_output_prev_wrap(struct sway_workspace *current,
bool should_wrap) {
if (should_wrap) {
return workspace_output_prev_next_impl(current->output, -1);
}
return workspace_output_prev_next_no_wrap_impl(current->output, -1);
}
struct sway_workspace *workspace_auto_back_and_forth(
struct sway_workspace *workspace) {
struct sway_seat *seat = input_manager_current_seat();