Compare commits
No commits in common. "23910437c47cb652a45000fde3b78641c4b1cd7f" and "4166fd372877fd59c1492df3015835ce2e594653" have entirely different histories.
23910437c4
...
4166fd3728
|
@ -90,60 +90,6 @@ char *gesture_parse(const char *input, struct gesture *output) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Similar to gesture_parse but with fewer checks to match the different
|
||||
// workspace_gesture syntax
|
||||
char *workspace_gesture_parse(const char *input, struct gesture *output) {
|
||||
// Clear output in case of failure
|
||||
output->type = GESTURE_TYPE_NONE;
|
||||
output->fingers = GESTURE_FINGERS_ANY;
|
||||
output->directions = GESTURE_DIRECTION_NONE;
|
||||
|
||||
// Split input type, fingers and directions
|
||||
list_t *split = split_string(input, ":");
|
||||
if (split->length < 1 || split->length > 2) {
|
||||
return format_str(
|
||||
"expected [:<fingers>][:direction], got %s",
|
||||
input);
|
||||
}
|
||||
|
||||
// Parse optional arguments
|
||||
if (split->length > 1) {
|
||||
char *next = split->items[0];
|
||||
|
||||
// Try to parse as finger count (1-9)
|
||||
if (strlen(next) == 1 && '1' <= next[0] && next[0] <= '9') {
|
||||
output->fingers = atoi(next);
|
||||
|
||||
// Move to next if available
|
||||
next = split->length == 2 ? split->items[1] : NULL;
|
||||
} else if (split->length == 2) {
|
||||
// Fail here if argument can only be finger count
|
||||
return format_str("expected 1-9, got %s", next);
|
||||
}
|
||||
|
||||
// If there is an argument left, try to parse as direction
|
||||
if (next) {
|
||||
list_t *directions = split_string(next, "+");
|
||||
|
||||
for (int i = 0; i < directions->length; ++i) {
|
||||
const char *item = directions->items[i];
|
||||
if (strcmp(item, "horizontal") == 0) {
|
||||
output->type = GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL;
|
||||
} else if (strcmp(item, "vertical") == 0) {
|
||||
output->type = GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL;
|
||||
} else {
|
||||
return format_str("expected direction, got %s", item);
|
||||
}
|
||||
}
|
||||
list_free_items_and_destroy(directions);
|
||||
}
|
||||
} // if optional args
|
||||
|
||||
list_free_items_and_destroy(split);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *gesture_type_string(enum gesture_type type) {
|
||||
switch (type) {
|
||||
case GESTURE_TYPE_NONE:
|
||||
|
@ -154,10 +100,6 @@ const char *gesture_type_string(enum gesture_type type) {
|
|||
return "pinch";
|
||||
case GESTURE_TYPE_SWIPE:
|
||||
return "swipe";
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL:
|
||||
return "workspace_swipe_horizontal";
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL:
|
||||
return "workspace_swipe_vertical";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -371,8 +313,6 @@ struct gesture *gesture_tracker_end(struct gesture_tracker *tracker) {
|
|||
}
|
||||
// Gesture without any direction
|
||||
case GESTURE_TYPE_HOLD:
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL:
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL:
|
||||
break;
|
||||
// Not tracking any gesture
|
||||
case GESTURE_TYPE_NONE:
|
||||
|
|
|
@ -12,8 +12,6 @@ enum gesture_type {
|
|||
GESTURE_TYPE_HOLD,
|
||||
GESTURE_TYPE_PINCH,
|
||||
GESTURE_TYPE_SWIPE,
|
||||
GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL,
|
||||
GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL,
|
||||
};
|
||||
|
||||
// Turns single type enum value to constant string representation.
|
||||
|
@ -59,13 +57,6 @@ struct gesture {
|
|||
*/
|
||||
char *gesture_parse(const char *input, struct gesture *output);
|
||||
|
||||
/**
|
||||
* Parses workspace gesture from [:<fingers>][:<directions>] string.
|
||||
*
|
||||
* Return NULL on success, otherwise error message string
|
||||
*/
|
||||
char *workspace_gesture_parse(const char *input, struct gesture *output);
|
||||
|
||||
// Turns gesture into string representation
|
||||
char *gesture_to_string(struct gesture *gesture);
|
||||
|
||||
|
|
|
@ -115,7 +115,6 @@ sway_cmd cmd_bindcode;
|
|||
sway_cmd cmd_bindgesture;
|
||||
sway_cmd cmd_bindswitch;
|
||||
sway_cmd cmd_bindsym;
|
||||
sway_cmd cmd_bindworkspacegesture;
|
||||
sway_cmd cmd_blur;
|
||||
sway_cmd cmd_blur_brightness;
|
||||
sway_cmd cmd_blur_contrast;
|
||||
|
@ -224,15 +223,11 @@ sway_cmd cmd_unbindcode;
|
|||
sway_cmd cmd_unbindswitch;
|
||||
sway_cmd cmd_unbindgesture;
|
||||
sway_cmd cmd_unbindsym;
|
||||
sway_cmd cmd_unbindworkspacegesture;
|
||||
sway_cmd cmd_unmark;
|
||||
sway_cmd cmd_urgent;
|
||||
sway_cmd cmd_workspace;
|
||||
sway_cmd cmd_workspace_layout;
|
||||
sway_cmd cmd_ws_auto_back_and_forth;
|
||||
sway_cmd cmd_ws_gesture_spring_size;
|
||||
sway_cmd cmd_ws_gesture_threshold;
|
||||
sway_cmd cmd_ws_gesture_wrap_around;
|
||||
sway_cmd cmd_xwayland;
|
||||
|
||||
sway_cmd bar_cmd_bindcode;
|
||||
|
|
|
@ -51,7 +51,6 @@ enum binding_flags {
|
|||
BINDING_INHIBITED = 1 << 7, // keyboard only: ignore shortcut inhibitor
|
||||
BINDING_NOREPEAT = 1 << 8, // keyboard only; do not trigger when repeating a held key
|
||||
BINDING_EXACT = 1 << 9, // gesture only; only trigger on exact match
|
||||
BINDING_INVERTED = 1 << 10, // workspace gesture only; gesture is inverted
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -502,10 +501,6 @@ struct sway_config {
|
|||
bool titlebar_separator;
|
||||
bool scratchpad_minimize;
|
||||
|
||||
int workspace_gesture_spring_size;
|
||||
bool workspace_gesture_wrap_around;
|
||||
float workspace_gesture_threshold;
|
||||
|
||||
list_t *layer_criteria;
|
||||
|
||||
char *swaynag_command;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#ifndef ANIMATION_UTILS_H
|
||||
#define ANIMATION_UTILS_H
|
||||
|
||||
double lerp (double a, double b, double t);
|
||||
|
||||
double ease_out_cubic (double t);
|
||||
|
||||
// TODO: Add more easing functions in the future like ease_in and ease_in_out, etc...
|
||||
|
||||
#endif
|
|
@ -15,19 +15,6 @@ struct decoration_data get_undecorated_decoration_data();
|
|||
struct sway_server;
|
||||
struct sway_container;
|
||||
|
||||
enum swipe_gesture_direction {
|
||||
SWIPE_GESTURE_DIRECTION_NONE,
|
||||
SWIPE_GESTURE_DIRECTION_HORIZONTAL,
|
||||
SWIPE_GESTURE_DIRECTION_VERTICAL,
|
||||
};
|
||||
|
||||
struct workspace_scroll {
|
||||
double percent;
|
||||
double avg_velocity;
|
||||
int num_updates;
|
||||
enum swipe_gesture_direction direction;
|
||||
};
|
||||
|
||||
struct decoration_data {
|
||||
float alpha;
|
||||
float saturation;
|
||||
|
@ -45,7 +32,6 @@ struct render_data {
|
|||
pixman_region32_t *damage;
|
||||
struct wlr_box *clip_box;
|
||||
struct decoration_data deco_data;
|
||||
bool on_focused_workspace;
|
||||
struct sway_view *view;
|
||||
};
|
||||
|
||||
|
@ -85,8 +71,6 @@ struct sway_output {
|
|||
struct wl_listener needs_frame;
|
||||
struct wl_listener request_state;
|
||||
|
||||
struct workspace_scroll workspace_scroll;
|
||||
|
||||
struct {
|
||||
struct wl_signal disable;
|
||||
} events;
|
||||
|
@ -243,20 +227,6 @@ void handle_output_manager_test(struct wl_listener *listener, void *data);
|
|||
void handle_output_power_manager_set_mode(struct wl_listener *listener,
|
||||
void *data);
|
||||
|
||||
struct workspace_scroll workspace_scroll_get_default();
|
||||
|
||||
bool workspace_scroll_equal(struct workspace_scroll *a, struct workspace_scroll *b);
|
||||
|
||||
void workspace_scroll_begin(struct sway_seat *seat,
|
||||
enum swipe_gesture_direction direction);
|
||||
|
||||
void workspace_scroll_update(struct sway_seat *seat, struct gesture_tracker *tracker,
|
||||
struct wlr_pointer_swipe_update_event *event, int invert);
|
||||
|
||||
void workspace_scroll_end(struct sway_seat *seat);
|
||||
|
||||
void workspace_scroll_reset(struct sway_seat *seat, struct sway_workspace *ws);
|
||||
|
||||
struct sway_output_non_desktop *output_non_desktop_create(struct wlr_output *wlr_output);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,13 +70,11 @@ struct sway_workspace *workspace_by_number(const char* name);
|
|||
|
||||
struct sway_workspace *workspace_by_name(const char*);
|
||||
|
||||
struct sway_workspace *workspace_output_next(struct sway_workspace *current,
|
||||
bool should_wrap);
|
||||
struct sway_workspace *workspace_output_next(struct sway_workspace *current);
|
||||
|
||||
struct sway_workspace *workspace_next(struct sway_workspace *current);
|
||||
|
||||
struct sway_workspace *workspace_output_prev(struct sway_workspace *current,
|
||||
bool should_wrap);
|
||||
struct sway_workspace *workspace_output_prev(struct sway_workspace *current);
|
||||
|
||||
struct sway_workspace *workspace_prev(struct sway_workspace *current);
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ static const struct cmd_handler handlers[] = {
|
|||
{ "bindgesture", cmd_bindgesture },
|
||||
{ "bindswitch", cmd_bindswitch },
|
||||
{ "bindsym", cmd_bindsym },
|
||||
{ "bindworkspacegesture", cmd_bindworkspacegesture },
|
||||
{ "blur", cmd_blur },
|
||||
{ "blur_brightness", cmd_blur_brightness },
|
||||
{ "blur_contrast", cmd_blur_contrast },
|
||||
|
@ -120,12 +119,8 @@ static const struct cmd_handler handlers[] = {
|
|||
{ "unbindgesture", cmd_unbindgesture },
|
||||
{ "unbindswitch", cmd_unbindswitch },
|
||||
{ "unbindsym", cmd_unbindsym },
|
||||
{ "unbindworkspacegesture", cmd_unbindworkspacegesture },
|
||||
{ "workspace", cmd_workspace },
|
||||
{ "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
|
||||
{ "workspace_gesture_spring_size", cmd_ws_gesture_spring_size },
|
||||
{ "workspace_gesture_threshold", cmd_ws_gesture_threshold },
|
||||
{ "workspace_gesture_wrap_around", cmd_ws_gesture_wrap_around },
|
||||
};
|
||||
|
||||
/* Config-time only commands. Keep alphabetized */
|
||||
|
|
|
@ -164,76 +164,3 @@ struct cmd_results *cmd_bindgesture(int argc, char **argv) {
|
|||
struct cmd_results *cmd_unbindgesture(int argc, char **argv) {
|
||||
return cmd_bind_or_unbind_gesture(argc, argv, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and execute bindgesture or unbindgesture command.
|
||||
*/
|
||||
static struct cmd_results *cmd_bind_or_unbind_workspacegesture(int argc,
|
||||
char **argv, bool unbind) {
|
||||
int minargs = 1;
|
||||
char *bindtype = "bindgesture";
|
||||
if (unbind) {
|
||||
bindtype = "unbindgesture";
|
||||
}
|
||||
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, bindtype, EXPECTED_AT_LEAST, minargs))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_gesture_binding *binding = calloc(1, sizeof(struct sway_gesture_binding));
|
||||
if (!binding) {
|
||||
return cmd_results_new(CMD_FAILURE, "Unable to allocate binding");
|
||||
}
|
||||
binding->input = strdup("*");
|
||||
|
||||
bool warn = true;
|
||||
|
||||
// Handle flags
|
||||
binding->flags |= BINDING_EXACT;
|
||||
while (argc > 0) {
|
||||
if (strcmp("--inverted", argv[0]) == 0) {
|
||||
binding->flags |= BINDING_INVERTED;
|
||||
} else if (strcmp("--no-warn", argv[0]) == 0) {
|
||||
warn = false;
|
||||
} else if (strncmp("--input-device=", argv[0],
|
||||
strlen("--input-device=")) == 0) {
|
||||
free(binding->input);
|
||||
binding->input = strdup(argv[0] + strlen("--input-device="));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (argc < minargs) {
|
||||
free(binding);
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"Invalid %s command (expected at least %d "
|
||||
"non-option arguments, got %d)", bindtype, minargs, argc);
|
||||
}
|
||||
|
||||
char* errmsg = NULL;
|
||||
if ((errmsg = workspace_gesture_parse(argv[0], &binding->gesture))) {
|
||||
free(binding);
|
||||
struct cmd_results *final = cmd_results_new(CMD_FAILURE,
|
||||
"Invalid %s command (%s)",
|
||||
bindtype, errmsg);
|
||||
free(errmsg);
|
||||
return final;
|
||||
}
|
||||
|
||||
if (unbind) {
|
||||
return gesture_binding_remove(binding, argv[0]);
|
||||
}
|
||||
binding->command = NULL;
|
||||
return gesture_binding_add(binding, argv[0], warn);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_bindworkspacegesture(int argc, char **argv) {
|
||||
return cmd_bind_or_unbind_workspacegesture(argc, argv, false);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_unbindworkspacegesture(int argc, char **argv) {
|
||||
return cmd_bind_or_unbind_workspacegesture(argc, argv, true);
|
||||
}
|
||||
|
|
|
@ -6,12 +6,10 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
#include "stringop.h"
|
||||
#include "util.h"
|
||||
|
||||
static struct workspace_config *workspace_config_find_or_create(char *ws_name) {
|
||||
struct workspace_config *wsc = workspace_find_config(ws_name);
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "util.h"
|
||||
|
||||
struct cmd_results *cmd_ws_gesture_spring_size(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "workspace_gesture_spring_size", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
char *inv;
|
||||
int value = strtol(argv[0], &inv, 10);
|
||||
if (*inv != '\0' || value < 0 || value > 250) {
|
||||
return cmd_results_new(CMD_FAILURE, "Invalid size specified");
|
||||
}
|
||||
|
||||
config->workspace_gesture_spring_size = value;
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_ws_gesture_wrap_around(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "workspace_gesture_wrap_around", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
config->workspace_gesture_wrap_around = parse_boolean(argv[0], true);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_ws_gesture_threshold(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "workspace_gesture_threshold", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
char *err;
|
||||
float val = strtof(argv[0], &err);
|
||||
if (*err || val < 0.1f || val > 0.9f) {
|
||||
return cmd_results_new(CMD_INVALID, "workspace_gesture_threshold float invalid. "
|
||||
"Should be between 0.1 and 0.9");
|
||||
}
|
||||
config->workspace_gesture_threshold = val;
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
|
@ -369,10 +369,6 @@ static void config_defaults(struct sway_config *config) {
|
|||
config->titlebar_separator = true;
|
||||
config->scratchpad_minimize = false;
|
||||
|
||||
config->workspace_gesture_spring_size = 50;
|
||||
config->workspace_gesture_wrap_around = false;
|
||||
config->workspace_gesture_threshold = 0.5;
|
||||
|
||||
if (!(config->layer_criteria = create_list())) goto cleanup;
|
||||
|
||||
// The keysym to keycode translation
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "log.h"
|
||||
#include "scenefx/render/pass.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/fx_util/animation_utils.h"
|
||||
#include "sway/desktop/transaction.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
|
@ -37,10 +36,6 @@
|
|||
#include "sway/tree/root.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "util.h"
|
||||
|
||||
#define PREV_WS_LIMIT -1.0f
|
||||
#define NEXT_WS_LIMIT 1.0f
|
||||
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
#include <wlr/backend/drm.h>
|
||||
|
@ -620,8 +615,7 @@ static int output_repaint_timer_handler(void *data) {
|
|||
|
||||
if (fullscreen_con && fullscreen_con->view && !debug.noscanout
|
||||
// Only output to monitor without compositing when saturation is changed
|
||||
&& fullscreen_con->saturation == 1.0f &&
|
||||
output->workspace_scroll.percent == 0.0f) {
|
||||
&& fullscreen_con->saturation == 1.0f) {
|
||||
// Try to scan-out the fullscreen view
|
||||
static bool last_scanned_out = false;
|
||||
bool scanned_out =
|
||||
|
@ -1120,8 +1114,6 @@ void handle_new_output(struct wl_listener *listener, void *data) {
|
|||
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
|
||||
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
|
||||
update_output_manager_config(server);
|
||||
|
||||
output->workspace_scroll = workspace_scroll_get_default();
|
||||
}
|
||||
|
||||
void handle_output_layout_change(struct wl_listener *listener,
|
||||
|
@ -1249,166 +1241,3 @@ void handle_output_power_manager_set_mode(struct wl_listener *listener,
|
|||
oc = store_output_config(oc);
|
||||
apply_output_config(oc, output);
|
||||
}
|
||||
|
||||
struct workspace_scroll workspace_scroll_get_default() {
|
||||
return (struct workspace_scroll) {
|
||||
.percent = 0,
|
||||
.avg_velocity = 0,
|
||||
.num_updates = 0,
|
||||
.direction = SWIPE_GESTURE_DIRECTION_NONE,
|
||||
};
|
||||
}
|
||||
|
||||
bool workspace_scroll_equal(struct workspace_scroll *a, struct workspace_scroll *b) {
|
||||
return a->avg_velocity == b->avg_velocity &&
|
||||
a->direction == b->direction &&
|
||||
a->num_updates == b->num_updates &&
|
||||
a->percent == b->percent;
|
||||
}
|
||||
|
||||
void workspace_scroll_begin(struct sway_seat *seat,
|
||||
enum swipe_gesture_direction direction) {
|
||||
struct sway_workspace *focused_ws = seat_get_focused_workspace(seat);
|
||||
struct sway_output *output = focused_ws->output;
|
||||
|
||||
// Reset the state
|
||||
output->workspace_scroll = workspace_scroll_get_default();
|
||||
output->workspace_scroll.direction = direction;
|
||||
|
||||
output_damage_whole(output);
|
||||
transaction_commit_dirty();
|
||||
|
||||
// Unset focus
|
||||
seat_set_focus_workspace(seat, NULL);
|
||||
}
|
||||
|
||||
void workspace_scroll_update(struct sway_seat *seat, struct gesture_tracker *tracker,
|
||||
struct wlr_pointer_swipe_update_event *event, int invert) {
|
||||
double delta_sum;
|
||||
enum swipe_gesture_direction direction;
|
||||
switch (tracker->type) {
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL:
|
||||
direction = SWIPE_GESTURE_DIRECTION_HORIZONTAL;
|
||||
delta_sum = tracker->dx + event->dx * invert;
|
||||
break;
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL:
|
||||
direction = SWIPE_GESTURE_DIRECTION_VERTICAL;
|
||||
delta_sum = tracker->dy + event->dy * invert;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
struct sway_workspace *focused_ws = seat_get_focused_workspace(seat);
|
||||
struct sway_output *output = focused_ws->output;
|
||||
struct workspace_scroll *ws_scroll = &output->workspace_scroll;
|
||||
|
||||
if (direction != ws_scroll->direction) {
|
||||
return;
|
||||
}
|
||||
|
||||
int visible_index = list_find(output->workspaces, focused_ws);
|
||||
if (visible_index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the updated average velocity
|
||||
ws_scroll->avg_velocity = fabs(delta_sum) / (++ws_scroll->num_updates);
|
||||
// TODO: Make configurable
|
||||
const int SPEED_FACTOR = 750;
|
||||
double percent = delta_sum / SPEED_FACTOR;
|
||||
|
||||
double min = PREV_WS_LIMIT, max = NEXT_WS_LIMIT;
|
||||
if (!config->workspace_gesture_wrap_around) {
|
||||
// Visualized to the user that this is the last / first workspace by
|
||||
// allowing a small eased swipe, a "Spring effect"
|
||||
double spring_limit = (double) config->workspace_gesture_spring_size /
|
||||
output->width * output->wlr_output->scale;
|
||||
// Make sure that the limit is always smaller than the threshold to
|
||||
// avoid accidental workspace switches
|
||||
double small_threshold = MAX(config->workspace_gesture_threshold - 0.1, 0);
|
||||
spring_limit = MIN(small_threshold, spring_limit);
|
||||
// Limit the percent depending on if the workspace is the first/last or in
|
||||
// the middle somewhere. Uses ease_out to make the limit feel more natural.
|
||||
if (visible_index + 1 >= output->workspaces->length) {
|
||||
max = spring_limit;
|
||||
if (percent > 0) {
|
||||
percent = lerp(0, max, ease_out_cubic(fabs(percent)));
|
||||
min = 0;
|
||||
}
|
||||
}
|
||||
if (visible_index == 0) {
|
||||
min = -spring_limit;
|
||||
if (percent < 0) {
|
||||
percent = lerp(0, min, ease_out_cubic(fabs(percent)));
|
||||
max = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the tracker data if we aren't exceeding the max swipe limit
|
||||
if (percent < max && percent > min) {
|
||||
tracker->dx += event->dx * invert;
|
||||
tracker->dy += event->dy * invert;
|
||||
}
|
||||
|
||||
ws_scroll->percent = CLAMP(percent, min, max);
|
||||
ws_scroll->direction = direction;
|
||||
|
||||
output_damage_whole(output);
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
void workspace_scroll_end(struct sway_seat *seat) {
|
||||
struct sway_workspace *focused_ws = seat_get_focused_workspace(seat);
|
||||
struct sway_output *output = focused_ws->output;
|
||||
struct workspace_scroll *ws_scroll = &output->workspace_scroll;
|
||||
|
||||
int visible_index = list_find(output->workspaces, focused_ws);
|
||||
|
||||
bool not_edge_ws = config->workspace_gesture_wrap_around;
|
||||
int dir;
|
||||
if (ws_scroll->percent < 0) {
|
||||
dir = PREV_WS_LIMIT;
|
||||
not_edge_ws |= visible_index > 0;
|
||||
} else if (ws_scroll->percent > 0) {
|
||||
dir = NEXT_WS_LIMIT;
|
||||
not_edge_ws |= visible_index + 1 < output->workspaces->length;
|
||||
} else {
|
||||
// Skip setting workspace if the percentage is zero
|
||||
goto reset_state;
|
||||
}
|
||||
|
||||
// TODO: Make configurable
|
||||
const int VELOCITY_NEEDED = 8;
|
||||
// Only switch workspaces when the percent exceeds the threshold or if
|
||||
// the avg_speed exceeds the limit (for fast but short swipes).
|
||||
bool threshold_met = fabs(ws_scroll->percent) >= config->workspace_gesture_threshold;
|
||||
bool enough_velocity = ws_scroll->avg_velocity >= VELOCITY_NEEDED && not_edge_ws;
|
||||
if (!threshold_met && !enough_velocity) {
|
||||
goto reset_state;
|
||||
}
|
||||
|
||||
size_t ws_index = wrap(visible_index + dir, output->workspaces->length);
|
||||
focused_ws = output->workspaces->items[ws_index];
|
||||
sway_log(SWAY_DEBUG, "Switched to workspace: %s\n", focused_ws->name);
|
||||
|
||||
reset_state:
|
||||
workspace_scroll_reset(seat, focused_ws);
|
||||
}
|
||||
|
||||
void workspace_scroll_reset(struct sway_seat *seat, struct sway_workspace *ws) {
|
||||
if (!ws) {
|
||||
ws = seat_get_focused_workspace(seat);
|
||||
}
|
||||
struct sway_output *output = ws->output;
|
||||
|
||||
workspace_switch(ws);
|
||||
seat_consider_warp_to_focus(seat);
|
||||
|
||||
// Reset the state
|
||||
output->workspace_scroll = workspace_scroll_get_default();
|
||||
|
||||
output_damage_whole(output);
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
|
|
|
@ -92,83 +92,6 @@ struct decoration_data get_undecorated_decoration_data() {
|
|||
};
|
||||
}
|
||||
|
||||
// Adjust the box position when switching the workspace
|
||||
static void adjust_box_to_workspace_offset(struct wlr_box *box,
|
||||
bool on_focused_workspace, struct sway_output *output) {
|
||||
float scroll_percent = output->workspace_scroll.percent;
|
||||
|
||||
int ws_dimen;
|
||||
int *box_coord = NULL;
|
||||
switch (output->workspace_scroll.direction) {
|
||||
case SWIPE_GESTURE_DIRECTION_NONE:
|
||||
return;
|
||||
case SWIPE_GESTURE_DIRECTION_HORIZONTAL:
|
||||
ws_dimen = output->width;
|
||||
box_coord = &box->x;
|
||||
break;
|
||||
case SWIPE_GESTURE_DIRECTION_VERTICAL:
|
||||
ws_dimen = output->height;
|
||||
box_coord = &box->y;
|
||||
break;
|
||||
}
|
||||
|
||||
if (box_coord == NULL || ws_dimen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
*box_coord -= ws_dimen * scroll_percent;
|
||||
if (!on_focused_workspace) {
|
||||
if (scroll_percent > 0) {
|
||||
*box_coord += ws_dimen;
|
||||
} else if (scroll_percent < 0) {
|
||||
*box_coord -= ws_dimen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clips the rendered damage to the workspace region.
|
||||
// Fixes containers being rendered across workspaces while switching.
|
||||
static void adjust_damage_to_workspace_bounds(pixman_region32_t *damage,
|
||||
bool on_focused_workspace, struct sway_output *output) {
|
||||
float scale = output->wlr_output->scale;
|
||||
float scroll_percent = output->workspace_scroll.percent;
|
||||
int x = 0, y = 0;
|
||||
|
||||
int ws_dimen = 0;
|
||||
int *coord = NULL;
|
||||
switch (output->workspace_scroll.direction) {
|
||||
case SWIPE_GESTURE_DIRECTION_NONE:
|
||||
return;
|
||||
case SWIPE_GESTURE_DIRECTION_HORIZONTAL:
|
||||
ws_dimen = output->width;
|
||||
coord = &x;
|
||||
break;
|
||||
case SWIPE_GESTURE_DIRECTION_VERTICAL:
|
||||
ws_dimen = output->height;
|
||||
coord = &y;
|
||||
break;
|
||||
}
|
||||
|
||||
if (coord == NULL || ws_dimen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
*coord = round(-ws_dimen * scroll_percent);
|
||||
if (!on_focused_workspace) {
|
||||
if (scroll_percent > 0) {
|
||||
*coord += ws_dimen;
|
||||
} else if (scroll_percent < 0) {
|
||||
*coord -= ws_dimen;
|
||||
}
|
||||
}
|
||||
|
||||
int width, height;
|
||||
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
|
||||
pixman_region32_intersect_rect(damage, damage,
|
||||
0, 0, width, height);
|
||||
pixman_region32_translate(damage, x * scale, y * scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply scale to a width or height.
|
||||
*
|
||||
|
@ -428,12 +351,6 @@ static void render_surface_iterator(struct sway_output *output,
|
|||
clip_box.x = fmax(dst_box.x, data->clip_box->x);
|
||||
clip_box.y = fmax(dst_box.y, data->clip_box->y);
|
||||
}
|
||||
|
||||
if (data->view) {
|
||||
adjust_box_to_workspace_offset(&dst_box, data->on_focused_workspace, output);
|
||||
adjust_box_to_workspace_offset(&clip_box, data->on_focused_workspace, output);
|
||||
}
|
||||
|
||||
scale_box(&dst_box, wlr_output->scale);
|
||||
scale_box(&clip_box, wlr_output->scale);
|
||||
|
||||
|
@ -504,7 +421,6 @@ static void render_layer_iterator(struct sway_output *output,
|
|||
static void render_layer_toplevel(struct fx_render_context *ctx, struct wl_list *layer_surfaces) {
|
||||
struct render_data data = {
|
||||
.deco_data = get_undecorated_decoration_data(),
|
||||
.on_focused_workspace = true,
|
||||
.ctx = ctx,
|
||||
};
|
||||
output_layer_for_each_toplevel_surface(ctx->output, layer_surfaces,
|
||||
|
@ -514,7 +430,6 @@ static void render_layer_toplevel(struct fx_render_context *ctx, struct wl_list
|
|||
static void render_layer_popups(struct fx_render_context *ctx, struct wl_list *layer_surfaces) {
|
||||
struct render_data data = {
|
||||
.deco_data = get_undecorated_decoration_data(),
|
||||
.on_focused_workspace = true,
|
||||
.ctx = ctx,
|
||||
};
|
||||
output_layer_for_each_popup_surface(ctx->output, layer_surfaces,
|
||||
|
@ -525,7 +440,6 @@ static void render_layer_toplevel(struct fx_render_context *ctx, struct wl_list
|
|||
static void render_unmanaged(struct fx_render_context *ctx, struct wl_list *unmanaged) {
|
||||
struct render_data data = {
|
||||
.deco_data = get_undecorated_decoration_data(),
|
||||
.on_focused_workspace = true,
|
||||
.ctx = ctx,
|
||||
};
|
||||
output_unmanaged_for_each_surface(ctx->output, unmanaged,
|
||||
|
@ -536,7 +450,6 @@ static void render_unmanaged(struct fx_render_context *ctx, struct wl_list *unma
|
|||
static void render_drag_icons(struct fx_render_context *ctx, struct wl_list *drag_icons) {
|
||||
struct render_data data = {
|
||||
.deco_data = get_undecorated_decoration_data(),
|
||||
.on_focused_workspace = true,
|
||||
.ctx = ctx,
|
||||
};
|
||||
output_drag_icons_for_each_surface(ctx->output, drag_icons,
|
||||
|
@ -635,10 +548,9 @@ void premultiply_alpha(float color[4], float opacity) {
|
|||
}
|
||||
|
||||
static void render_view_toplevels(struct fx_render_context *ctx,
|
||||
struct sway_view *view, struct decoration_data deco_data, bool on_focused_workspace) {
|
||||
struct sway_view *view, struct decoration_data deco_data) {
|
||||
struct render_data data = {
|
||||
.deco_data = deco_data,
|
||||
.on_focused_workspace = on_focused_workspace,
|
||||
.view = view,
|
||||
.ctx = ctx,
|
||||
};
|
||||
|
@ -686,7 +598,6 @@ static void render_view_popups(struct fx_render_context *ctx, struct sway_view *
|
|||
struct decoration_data deco_data) {
|
||||
struct render_data data = {
|
||||
.deco_data = deco_data,
|
||||
.on_focused_workspace = true,
|
||||
.view = view,
|
||||
.ctx = ctx,
|
||||
};
|
||||
|
@ -789,14 +700,13 @@ static void render_saved_view(struct fx_render_context *ctx, struct sway_view *v
|
|||
* Render a view's surface, shadow, and left/bottom/right borders.
|
||||
*/
|
||||
static void render_view(struct fx_render_context *ctx, struct sway_container *con,
|
||||
struct border_colors *colors, struct decoration_data deco_data,
|
||||
bool on_focused_workspace) {
|
||||
struct border_colors *colors, struct decoration_data deco_data) {
|
||||
struct sway_view *view = con->view;
|
||||
|
||||
if (!wl_list_empty(&view->saved_buffers)) {
|
||||
render_saved_view(ctx, view, deco_data);
|
||||
} else if (view->surface) {
|
||||
render_view_toplevels(ctx, view, deco_data, on_focused_workspace);
|
||||
render_view_toplevels(ctx, view, deco_data);
|
||||
}
|
||||
|
||||
struct sway_container_state *state = &con->current;
|
||||
|
@ -815,7 +725,6 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
|
|||
box.y = floor(state->y) - ctx->output->ly;
|
||||
box.width = state->width;
|
||||
box.height = state->height;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
scale_box(&box, output_scale);
|
||||
int shadow_corner_radius = corner_radius == 0 ? 0 : corner_radius + state->border_thickness;
|
||||
float* shadow_color = view_is_urgent(view) || state->focused ?
|
||||
|
@ -839,7 +748,6 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
|
|||
box.y = floor(state->content_y);
|
||||
box.width = state->border_thickness;
|
||||
box.height = state->content_height - corner_radius;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
if (corner_radius && !deco_data.has_titlebar) {
|
||||
box.y += corner_radius;
|
||||
box.height -= corner_radius;
|
||||
|
@ -863,7 +771,6 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
|
|||
box.y = floor(state->content_y);
|
||||
box.width = state->border_thickness;
|
||||
box.height = state->content_height - corner_radius;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
if (corner_radius && !deco_data.has_titlebar) {
|
||||
box.y += corner_radius;
|
||||
box.height -= corner_radius;
|
||||
|
@ -883,8 +790,6 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
|
|||
box.y = floor(state->content_y + state->content_height);
|
||||
box.width = state->width;
|
||||
box.height = state->border_thickness;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
|
||||
// adjust sizing for rounded border corners
|
||||
if (deco_data.corner_radius) {
|
||||
box.x += corner_radius + state->border_thickness;
|
||||
|
@ -900,7 +805,6 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
|
|||
if (state->border_left) {
|
||||
box.x = floor(state->x);
|
||||
box.y = floor(state->y + state->height - size);
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
box.width = size;
|
||||
box.height = size;
|
||||
scale_box(&box, output_scale);
|
||||
|
@ -910,7 +814,8 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
|
|||
if (state->border_right) {
|
||||
box.x = floor(state->x + state->width - size);
|
||||
box.y = floor(state->y + state->height - size);
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
box.width = size;
|
||||
box.height = size;
|
||||
scale_box(&box, output_scale);
|
||||
render_rounded_border_corner(ctx, &box, color, scaled_corner_radius,
|
||||
scaled_border_thickness, BOTTOM_RIGHT);
|
||||
|
@ -931,7 +836,7 @@ static void render_view(struct fx_render_context *ctx, struct sway_container *co
|
|||
static void render_titlebar(struct fx_render_context *ctx, struct sway_container *con,
|
||||
int x, int y, int width, struct border_colors *colors, int corner_radius,
|
||||
enum corner_location corner_location, struct wlr_texture *title_texture,
|
||||
struct wlr_texture *marks_texture, bool on_focused_workspace) {
|
||||
struct wlr_texture *marks_texture) {
|
||||
struct wlr_box box;
|
||||
float color[4];
|
||||
struct sway_output *output = ctx->output;
|
||||
|
@ -963,7 +868,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.width -= corner_radius;
|
||||
}
|
||||
}
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
scale_box(&box, output_scale);
|
||||
render_rect(ctx, &box, color);
|
||||
|
||||
|
@ -973,7 +877,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.y = y + container_titlebar_height() - titlebar_border_thickness;
|
||||
box.width = width;
|
||||
box.height = titlebar_border_thickness;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
scale_box(&box, output_scale);
|
||||
render_rect(ctx, &box, color);
|
||||
}
|
||||
|
@ -987,7 +890,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.height -= corner_radius;
|
||||
box.y += corner_radius;
|
||||
}
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
scale_box(&box, output_scale);
|
||||
render_rect(ctx, &box, color);
|
||||
|
||||
|
@ -1000,7 +902,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.height -= corner_radius;
|
||||
box.y += corner_radius;
|
||||
}
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
scale_box(&box, output_scale);
|
||||
render_rect(ctx, &box, color);
|
||||
|
||||
|
@ -1012,7 +913,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.y = y;
|
||||
box.width = corner_radius * 2;
|
||||
box.height = corner_radius * 2;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
scale_box(&box, output_scale);
|
||||
render_rounded_border_corner(ctx, &box, color, corner_radius,
|
||||
titlebar_border_thickness * output_scale, TOP_LEFT);
|
||||
|
@ -1024,7 +924,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.y = y;
|
||||
box.width = corner_radius * 2;
|
||||
box.height = corner_radius * 2;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
scale_box(&box, output_scale);
|
||||
render_rounded_border_corner(ctx, &box, color, corner_radius,
|
||||
titlebar_border_thickness * output_scale, TOP_RIGHT);
|
||||
|
@ -1078,7 +977,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
if (ob_inner_width < clip_box.width) {
|
||||
clip_box.width = ob_inner_width;
|
||||
}
|
||||
adjust_box_to_workspace_offset(&texture_box, on_focused_workspace, output);
|
||||
render_texture(ctx, marks_texture,
|
||||
NULL, &texture_box, &clip_box, WL_OUTPUT_TRANSFORM_NORMAL, deco_data);
|
||||
|
||||
|
@ -1089,13 +987,11 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.y = roundf((y + titlebar_border_thickness) * output_scale);
|
||||
box.width = clip_box.width;
|
||||
box.height = ob_padding_above;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
render_rect(ctx, &box, color);
|
||||
|
||||
// Padding below
|
||||
box.y += ob_padding_above + clip_box.height;
|
||||
box.height = ob_padding_below + bottom_border_compensation;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
render_rect(ctx, &box, color);
|
||||
}
|
||||
|
||||
|
@ -1153,8 +1049,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
clip_box.width = ob_inner_width - ob_marks_width;
|
||||
}
|
||||
|
||||
adjust_box_to_workspace_offset(&texture_box, on_focused_workspace, output);
|
||||
adjust_box_to_workspace_offset(&clip_box, on_focused_workspace, output);
|
||||
render_texture(ctx, title_texture,
|
||||
NULL, &texture_box, &clip_box, WL_OUTPUT_TRANSFORM_NORMAL, deco_data);
|
||||
|
||||
|
@ -1165,7 +1059,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.y = roundf((y + titlebar_border_thickness) * output_scale);
|
||||
box.width = clip_box.width;
|
||||
box.height = ob_padding_above;
|
||||
// adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
render_rect(ctx, &box, color);
|
||||
|
||||
// Padding below
|
||||
|
@ -1205,7 +1098,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.x = ob_left_x + ob_left_width + round(output_x * output_scale);
|
||||
box.y = roundf(bg_y * output_scale);
|
||||
box.height = ob_bg_height + bottom_border_compensation;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
render_rect(ctx, &box, color);
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1112,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
if (box.x + box.width < left_x) {
|
||||
box.width += left_x - box.x - box.width;
|
||||
}
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
if (corner_radius && (corner_location == TOP_LEFT || corner_location == ALL)) {
|
||||
render_rounded_rect(ctx, &box, color, corner_radius, TOP_LEFT);
|
||||
} else {
|
||||
|
@ -1239,7 +1130,6 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
box.width += box.x - right_rx;
|
||||
box.x = right_rx;
|
||||
}
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, output);
|
||||
if (corner_radius && (corner_location == TOP_RIGHT || corner_location == ALL)) {
|
||||
render_rounded_rect(ctx, &box, color, corner_radius, TOP_RIGHT);
|
||||
} else {
|
||||
|
@ -1251,7 +1141,7 @@ static void render_titlebar(struct fx_render_context *ctx, struct sway_container
|
|||
* Render the top border line for a view using "border pixel".
|
||||
*/
|
||||
static void render_top_border(struct fx_render_context *ctx, struct sway_container *con,
|
||||
struct border_colors *colors, int corner_radius, bool on_focused_workspace) {
|
||||
struct border_colors *colors, int corner_radius) {
|
||||
struct sway_container_state *state = &con->current;
|
||||
if (!state->border_top) {
|
||||
return;
|
||||
|
@ -1267,7 +1157,6 @@ static void render_top_border(struct fx_render_context *ctx, struct sway_contain
|
|||
box.y = floor(state->y);
|
||||
box.width = state->width - (2 * corner_radius);
|
||||
box.height = state->border_thickness;
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
scale_box(&box, output_scale);
|
||||
render_rect(ctx, &box, color);
|
||||
|
||||
|
@ -1278,7 +1167,6 @@ static void render_top_border(struct fx_render_context *ctx, struct sway_contain
|
|||
if (state->border_left) {
|
||||
box.x = floor(state->x);
|
||||
box.y = floor(state->y);
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
box.width = size;
|
||||
box.height = size;
|
||||
scale_box(&box, output_scale);
|
||||
|
@ -1288,7 +1176,6 @@ static void render_top_border(struct fx_render_context *ctx, struct sway_contain
|
|||
if (state->border_right) {
|
||||
box.x = floor(state->x + state->width - size);
|
||||
box.y = floor(state->y);
|
||||
adjust_box_to_workspace_offset(&box, on_focused_workspace, ctx->output);
|
||||
box.width = size;
|
||||
box.height = size;
|
||||
scale_box(&box, output_scale);
|
||||
|
@ -1304,13 +1191,10 @@ struct parent_data {
|
|||
list_t *children;
|
||||
bool focused;
|
||||
struct sway_container *active_child;
|
||||
|
||||
// Indicates whether the target is on the focused workspace or not.
|
||||
bool on_focused_workspace;
|
||||
};
|
||||
|
||||
static void render_container(struct fx_render_context *ctx,
|
||||
struct sway_container *con, bool parent_focused, bool is_current_ws);
|
||||
struct sway_container *con, bool parent_focused);
|
||||
|
||||
// TODO: no rounding top corners when rendering with titlebar
|
||||
/**
|
||||
|
@ -1370,18 +1254,17 @@ static void render_containers_linear(struct fx_render_context *ctx, struct paren
|
|||
.discard_transparent = false,
|
||||
.shadow = child->shadow_enabled,
|
||||
};
|
||||
render_view(ctx, child, colors, deco_data, parent->on_focused_workspace);
|
||||
render_view(ctx, child, colors, deco_data);
|
||||
if (has_titlebar) {
|
||||
render_titlebar(ctx, child, floor(state->x), floor(state->y),
|
||||
state->width, colors, deco_data.corner_radius,
|
||||
ALL, title_texture, marks_texture, parent->on_focused_workspace);
|
||||
ALL, title_texture, marks_texture);
|
||||
} else if (state->border == B_PIXEL) {
|
||||
render_top_border(ctx, child, colors, deco_data.corner_radius, parent->on_focused_workspace);
|
||||
render_top_border(ctx, child, colors, deco_data.corner_radius);
|
||||
}
|
||||
} else {
|
||||
render_container(ctx, child,
|
||||
parent->focused || child->current.focused,
|
||||
parent->on_focused_workspace);
|
||||
parent->focused || child->current.focused);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1476,8 +1359,7 @@ static void render_containers_tabbed(struct fx_render_context *ctx, struct paren
|
|||
}
|
||||
|
||||
render_titlebar(ctx, child, x, parent->box.y, tab_width, colors,
|
||||
corner_radius, corner_location, title_texture, marks_texture,
|
||||
parent->on_focused_workspace);
|
||||
corner_radius, corner_location, title_texture, marks_texture);
|
||||
|
||||
if (child == current) {
|
||||
current_colors = colors;
|
||||
|
@ -1486,12 +1368,10 @@ static void render_containers_tabbed(struct fx_render_context *ctx, struct paren
|
|||
|
||||
// Render surface and left/right/bottom borders
|
||||
if (current->view) {
|
||||
render_view(ctx, current, current_colors, deco_data,
|
||||
parent->on_focused_workspace);
|
||||
render_view(ctx, current, current_colors, deco_data);
|
||||
} else {
|
||||
render_container(ctx, current,
|
||||
parent->focused || current->current.focused,
|
||||
parent->on_focused_workspace);
|
||||
parent->focused || current->current.focused);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1558,7 +1438,7 @@ static void render_containers_stacked(struct fx_render_context *ctx, struct pare
|
|||
int y = parent->box.y + titlebar_height * i;
|
||||
int corner_radius = i != 0 ? 0 : deco_data.corner_radius;
|
||||
render_titlebar(ctx, child, parent->box.x, y, parent->box.width, colors,
|
||||
corner_radius, ALL, title_texture, marks_texture, parent->on_focused_workspace);
|
||||
corner_radius, ALL, title_texture, marks_texture);
|
||||
|
||||
if (child == current) {
|
||||
current_colors = colors;
|
||||
|
@ -1567,12 +1447,10 @@ static void render_containers_stacked(struct fx_render_context *ctx, struct pare
|
|||
|
||||
// Render surface and left/right/bottom borders
|
||||
if (current->view) {
|
||||
render_view(ctx, current, current_colors, deco_data,
|
||||
parent->on_focused_workspace);
|
||||
render_view(ctx, current, current_colors, deco_data);
|
||||
} else {
|
||||
render_container(ctx, current,
|
||||
parent->focused || current->current.focused,
|
||||
parent->on_focused_workspace);
|
||||
parent->focused || current->current.focused);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1601,7 +1479,7 @@ static void render_containers(struct fx_render_context *ctx, struct parent_data
|
|||
}
|
||||
|
||||
static void render_container(struct fx_render_context *ctx,
|
||||
struct sway_container *con, bool focused, bool is_focused_ws) {
|
||||
struct sway_container *con, bool focused) {
|
||||
struct parent_data data = {
|
||||
.layout = con->current.layout,
|
||||
.box = {
|
||||
|
@ -1613,13 +1491,12 @@ static void render_container(struct fx_render_context *ctx,
|
|||
.children = con->current.children,
|
||||
.focused = focused,
|
||||
.active_child = con->current.focused_inactive_child,
|
||||
.on_focused_workspace = is_focused_ws,
|
||||
};
|
||||
render_containers(ctx, &data);
|
||||
}
|
||||
|
||||
static void render_workspace(struct fx_render_context *ctx,
|
||||
struct sway_workspace *ws, bool focused, bool on_focused_workspace) {
|
||||
struct sway_workspace *ws, bool focused) {
|
||||
struct parent_data data = {
|
||||
.layout = ws->current.layout,
|
||||
.box = {
|
||||
|
@ -1631,13 +1508,12 @@ static void render_workspace(struct fx_render_context *ctx,
|
|||
.children = ws->current.tiling,
|
||||
.focused = focused,
|
||||
.active_child = ws->current.focused_inactive_child,
|
||||
.on_focused_workspace = on_focused_workspace,
|
||||
};
|
||||
render_containers(ctx, &data);
|
||||
}
|
||||
|
||||
static void render_floating_container(struct fx_render_context *ctx,
|
||||
struct sway_container *con, bool is_focused_ws) {
|
||||
struct sway_container *con) {
|
||||
struct sway_container_state *state = &con->current;
|
||||
if (con->view) {
|
||||
struct sway_view *view = con->view;
|
||||
|
@ -1673,44 +1549,32 @@ static void render_floating_container(struct fx_render_context *ctx,
|
|||
.discard_transparent = false,
|
||||
.shadow = con->shadow_enabled,
|
||||
};
|
||||
render_view(ctx, con, colors, deco_data, is_focused_ws);
|
||||
render_view(ctx, con, colors, deco_data);
|
||||
if (has_titlebar) {
|
||||
render_titlebar(ctx, con, floor(con->current.x), floor(con->current.y), con->current.width,
|
||||
colors, deco_data.corner_radius, ALL, title_texture, marks_texture, is_focused_ws);
|
||||
colors, deco_data.corner_radius, ALL, title_texture, marks_texture);
|
||||
} else if (state->border == B_PIXEL) {
|
||||
render_top_border(ctx, con, colors, deco_data.corner_radius, is_focused_ws);
|
||||
render_top_border(ctx, con, colors, deco_data.corner_radius);
|
||||
}
|
||||
} else {
|
||||
render_container(ctx, con, state->focused, is_focused_ws);
|
||||
render_container(ctx, con, state->focused);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_floating(struct fx_render_context *ctx,
|
||||
struct sway_workspace *other_ws, bool has_fullscreen) {
|
||||
static void render_floating(struct fx_render_context *ctx) {
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
|
||||
// Don't render floating windows across outputs when switching workspaces
|
||||
if (output->workspace_scroll.percent != 0 && output != ctx->output) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct sway_workspace *visible_ws = output->current.active_workspace;
|
||||
for (int j = 0; j < output->current.workspaces->length; ++j) {
|
||||
struct sway_workspace *ws = output->current.workspaces->items[j];
|
||||
|
||||
// Only render affected workspaces
|
||||
if ((ws != other_ws && ws != visible_ws) ||
|
||||
(workspace_is_visible(ws) && has_fullscreen)) {
|
||||
if (!workspace_is_visible(ws)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int k = 0; k < ws->current.floating->length; ++k) {
|
||||
struct sway_container *floater = ws->current.floating->items[k];
|
||||
if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
|
||||
continue;
|
||||
}
|
||||
render_floating_container(ctx, floater, ws == visible_ws);
|
||||
render_floating_container(ctx, floater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1723,57 +1587,6 @@ static void render_seatops(struct fx_render_context *ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
static void render_fullscreen_con(struct fx_render_context *ctx,
|
||||
pixman_region32_t *transformed_damage, struct sway_container *fullscreen_con,
|
||||
struct sway_workspace *workspace, bool clear_whole_screen) {
|
||||
struct wlr_output *wlr_output = ctx->output->wlr_output;
|
||||
|
||||
bool on_focused_workspace = workspace == ctx->output->current.active_workspace;
|
||||
|
||||
// Only clear the transformed fullscreen bounds
|
||||
pixman_region32_t dmg;
|
||||
pixman_region32_init(&dmg);
|
||||
if (!clear_whole_screen) {
|
||||
pixman_region32_copy(&dmg, transformed_damage);
|
||||
adjust_damage_to_workspace_bounds(&dmg, on_focused_workspace, ctx->output);
|
||||
transformed_damage = &dmg;
|
||||
}
|
||||
|
||||
|
||||
fx_render_pass_add_rect(ctx->pass, &(struct fx_render_rect_options){
|
||||
.base = {
|
||||
.box = { .width = wlr_output->width, .height = wlr_output->height },
|
||||
.color = { .r = 0, .g = 0, .b = 0, .a = 1 },
|
||||
.clip = transformed_damage,
|
||||
},
|
||||
});
|
||||
|
||||
if (fullscreen_con->view) {
|
||||
struct decoration_data deco_data = get_undecorated_decoration_data();
|
||||
deco_data.saturation = fullscreen_con->saturation;
|
||||
if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
|
||||
render_saved_view(ctx, fullscreen_con->view, deco_data);
|
||||
} else if (fullscreen_con->view->surface) {
|
||||
render_view_toplevels(ctx, fullscreen_con->view, deco_data, on_focused_workspace);
|
||||
}
|
||||
} else {
|
||||
render_container(ctx, fullscreen_con, fullscreen_con->current.focused, on_focused_workspace);
|
||||
}
|
||||
|
||||
for (int i = 0; i < workspace->current.floating->length; ++i) {
|
||||
struct sway_container *floater =
|
||||
workspace->current.floating->items[i];
|
||||
if (container_is_transient_for(floater, fullscreen_con)) {
|
||||
render_floating_container(ctx, floater, on_focused_workspace);
|
||||
}
|
||||
}
|
||||
#if HAVE_XWAYLAND
|
||||
render_unmanaged(ctx, &root->xwayland_unmanaged);
|
||||
#endif
|
||||
|
||||
pixman_region32_fini(&dmg);
|
||||
}
|
||||
|
||||
void output_render(struct fx_render_context *ctx) {
|
||||
struct wlr_output *wlr_output = ctx->output->wlr_output;
|
||||
struct sway_output *output = ctx->output;
|
||||
|
@ -1786,29 +1599,10 @@ void output_render(struct fx_render_context *ctx) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get the sibling workspaces
|
||||
struct sway_workspace *other_ws = NULL;
|
||||
if (output->workspace_scroll.percent < 0) {
|
||||
other_ws = workspace_output_prev(workspace,
|
||||
config->workspace_gesture_wrap_around);
|
||||
} else if (output->workspace_scroll.percent > 0) {
|
||||
other_ws = workspace_output_next(workspace,
|
||||
config->workspace_gesture_wrap_around);
|
||||
}
|
||||
|
||||
struct sway_container *fullscreen_con = root->fullscreen_global;
|
||||
if (!fullscreen_con) {
|
||||
fullscreen_con = workspace->current.fullscreen;
|
||||
}
|
||||
// Also check if the sibling workspace has a fullscreen container
|
||||
bool has_fullscreen = fullscreen_con != NULL;
|
||||
bool other_ws_has_fullscreen = false;
|
||||
if (other_ws) {
|
||||
other_ws_has_fullscreen = other_ws->current.fullscreen;
|
||||
if (!has_fullscreen) {
|
||||
has_fullscreen = other_ws_has_fullscreen;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pixman_region32_not_empty(damage)) {
|
||||
// Output isn't damaged but needs buffer swap
|
||||
|
@ -1849,7 +1643,6 @@ void output_render(struct fx_render_context *ctx) {
|
|||
if (server.session_lock.lock != NULL) {
|
||||
struct render_data data = {
|
||||
.deco_data = get_undecorated_decoration_data(),
|
||||
.on_focused_workspace = true,
|
||||
.ctx = ctx,
|
||||
};
|
||||
|
||||
|
@ -1873,9 +1666,37 @@ void output_render(struct fx_render_context *ctx) {
|
|||
goto render_overlay;
|
||||
}
|
||||
|
||||
if (fullscreen_con && output->workspace_scroll.percent == 0) {
|
||||
// Only draw fullscreen con if not transitioning between workspaces
|
||||
render_fullscreen_con(ctx, &transformed_damage, fullscreen_con, workspace, true);
|
||||
if (fullscreen_con) {
|
||||
fx_render_pass_add_rect(ctx->pass, &(struct fx_render_rect_options){
|
||||
.base = {
|
||||
.box = { .width = wlr_output->width, .height = wlr_output->height },
|
||||
.color = { .r = 0, .g = 0, .b = 0, .a = 1 },
|
||||
.clip = &transformed_damage,
|
||||
},
|
||||
});
|
||||
|
||||
if (fullscreen_con->view) {
|
||||
struct decoration_data deco_data = get_undecorated_decoration_data();
|
||||
deco_data.saturation = fullscreen_con->saturation;
|
||||
if (!wl_list_empty(&fullscreen_con->view->saved_buffers)) {
|
||||
render_saved_view(ctx, fullscreen_con->view, deco_data);
|
||||
} else if (fullscreen_con->view->surface) {
|
||||
render_view_toplevels(ctx, fullscreen_con->view, deco_data);
|
||||
}
|
||||
} else {
|
||||
render_container(ctx, fullscreen_con, fullscreen_con->current.focused);
|
||||
}
|
||||
|
||||
for (int i = 0; i < workspace->current.floating->length; ++i) {
|
||||
struct sway_container *floater =
|
||||
workspace->current.floating->items[i];
|
||||
if (container_is_transient_for(floater, fullscreen_con)) {
|
||||
render_floating_container(ctx, floater);
|
||||
}
|
||||
}
|
||||
#if HAVE_XWAYLAND
|
||||
render_unmanaged(ctx, &root->xwayland_unmanaged);
|
||||
#endif
|
||||
} else {
|
||||
int output_width, output_height;
|
||||
wlr_output_transformed_resolution(wlr_output, &output_width, &output_height);
|
||||
|
@ -1958,16 +1779,8 @@ void output_render(struct fx_render_context *ctx) {
|
|||
fx_render_pass_add_optimized_blur(ctx->pass, &blur_options);
|
||||
}
|
||||
|
||||
// Render both workspaces
|
||||
if (!other_ws_has_fullscreen && other_ws) {
|
||||
render_workspace(ctx, other_ws, false, false);
|
||||
}
|
||||
if (!fullscreen_con) {
|
||||
render_workspace(ctx, workspace, workspace->current.focused, true);
|
||||
}
|
||||
render_floating(ctx,
|
||||
!other_ws_has_fullscreen ? other_ws : NULL,
|
||||
fullscreen_con != NULL);
|
||||
render_workspace(ctx, workspace, workspace->current.focused);
|
||||
render_floating(ctx);
|
||||
#if HAVE_XWAYLAND
|
||||
render_unmanaged(ctx, &root->xwayland_unmanaged);
|
||||
#endif
|
||||
|
@ -1980,43 +1793,6 @@ void output_render(struct fx_render_context *ctx) {
|
|||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
|
||||
render_layer_popups(ctx,
|
||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
|
||||
|
||||
// Render the fullscreen containers on top
|
||||
if (has_fullscreen) {
|
||||
float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
|
||||
// Render a blank rect next to the fullscreen container if
|
||||
// there's no sibling workspace in the swipes direction
|
||||
if (!other_ws) {
|
||||
struct wlr_box mon_box = { 0, 0, output->width, output->height };
|
||||
adjust_box_to_workspace_offset(&mon_box, false, output);
|
||||
scale_box(&mon_box, output->wlr_output->scale);
|
||||
render_rect(ctx, &mon_box, clear_color);
|
||||
|
||||
// Render a shadow to separate the edge and the fullscreen
|
||||
// container
|
||||
if (config_should_parameters_shadow()) {
|
||||
struct wlr_box shadow_box = { 0, 0, output->width, output->height };
|
||||
adjust_box_to_workspace_offset(&shadow_box, true, output);
|
||||
scale_box(&shadow_box, output->wlr_output->scale);
|
||||
// Render rect to fix minor pixel gaps between fullscreen
|
||||
// container and shadow
|
||||
render_rect(ctx, &shadow_box, clear_color);
|
||||
render_box_shadow(ctx, &shadow_box,
|
||||
config->shadow_color, config->shadow_blur_sigma, 0,
|
||||
0, 0);
|
||||
}
|
||||
} else {
|
||||
// Render sibling fullscreen container
|
||||
struct sway_container *f_con = other_ws->current.fullscreen;
|
||||
if (other_ws->current.fullscreen) {
|
||||
render_fullscreen_con(ctx, &transformed_damage, f_con, other_ws, false);
|
||||
}
|
||||
}
|
||||
// Render focused fullscreen container
|
||||
if (fullscreen_con) {
|
||||
render_fullscreen_con(ctx, &transformed_damage, fullscreen_con, workspace, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_seatops(ctx);
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#include <math.h>
|
||||
|
||||
#include "sway/fx_util/animation_utils.h"
|
||||
|
||||
double lerp (double a, double b, double t) {
|
||||
return a * (1.0 - t) + b * t;
|
||||
}
|
||||
|
||||
double ease_out_cubic (double t) {
|
||||
double p = t - 1;
|
||||
return pow(p, 3) + 1;
|
||||
}
|
|
@ -1053,14 +1053,6 @@ static void handle_swipe_begin(struct sway_seat *seat,
|
|||
if (gesture_binding_check(bindings, GESTURE_TYPE_SWIPE, event->fingers, device)) {
|
||||
struct seatop_default_event *seatop = seat->seatop_data;
|
||||
gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_SWIPE, event->fingers);
|
||||
} else if (gesture_binding_check(bindings, GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL, event->fingers, device)) {
|
||||
struct seatop_default_event *seatop = seat->seatop_data;
|
||||
gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL, event->fingers);
|
||||
workspace_scroll_begin(seat, SWIPE_GESTURE_DIRECTION_HORIZONTAL);
|
||||
} else if (gesture_binding_check(bindings, GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL, event->fingers, device)) {
|
||||
struct seatop_default_event *seatop = seat->seatop_data;
|
||||
gesture_tracker_begin(&seatop->gestures, GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL, event->fingers);
|
||||
workspace_scroll_begin(seat, SWIPE_GESTURE_DIRECTION_VERTICAL);
|
||||
} else {
|
||||
// ... otherwise forward to client
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
|
@ -1078,29 +1070,6 @@ static void handle_swipe_update(struct sway_seat *seat,
|
|||
if (gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE)) {
|
||||
gesture_tracker_update(&seatop->gestures,
|
||||
event->dx, event->dy, NAN, NAN);
|
||||
} else if (gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL) ||
|
||||
gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL)) {
|
||||
// Find the gesture and update the swipe percentage
|
||||
struct gesture_tracker *tracker = &seatop->gestures;
|
||||
struct sway_input_device *device =
|
||||
event->pointer ? event->pointer->base.data : NULL;
|
||||
// Determine name of input that received gesture
|
||||
char *input = device
|
||||
? input_device_get_identifier(device->wlr_device)
|
||||
: strdup("*");
|
||||
|
||||
struct gesture gesture = {
|
||||
.fingers = tracker->fingers,
|
||||
.type = tracker->type,
|
||||
.directions = GESTURE_DIRECTION_NONE,
|
||||
};
|
||||
struct sway_gesture_binding *binding = gesture_binding_match(
|
||||
config->current_mode->gesture_bindings, &gesture, input);
|
||||
|
||||
if (binding) {
|
||||
int invert = binding->flags & BINDING_INVERTED ? 1 : -1;
|
||||
workspace_scroll_update(seat, tracker, event, invert);
|
||||
}
|
||||
} else {
|
||||
// ... otherwise forward to client
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
|
@ -1114,17 +1083,13 @@ static void handle_swipe_end(struct sway_seat *seat,
|
|||
struct wlr_pointer_swipe_end_event *event) {
|
||||
// Ensure gesture is being tracked and was not cancelled
|
||||
struct seatop_default_event *seatop = seat->seatop_data;
|
||||
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE) &&
|
||||
!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL) &&
|
||||
!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL)) {
|
||||
if (!gesture_tracker_check(&seatop->gestures, GESTURE_TYPE_SWIPE)) {
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
wlr_pointer_gestures_v1_send_swipe_end(server.input->pointer_gestures,
|
||||
cursor->seat->wlr_seat, event->time_msec, event->cancelled);
|
||||
return;
|
||||
}
|
||||
if (event->cancelled &&
|
||||
seatop->gestures.type != GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL
|
||||
&& seatop->gestures.type != GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL) {
|
||||
if (event->cancelled) {
|
||||
gesture_tracker_cancel(&seatop->gestures);
|
||||
return;
|
||||
}
|
||||
|
@ -1136,15 +1101,7 @@ static void handle_swipe_end(struct sway_seat *seat,
|
|||
&seatop->gestures, device);
|
||||
|
||||
if (binding) {
|
||||
switch (binding->gesture.type) {
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL:
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL:
|
||||
workspace_scroll_end(seat);
|
||||
break;
|
||||
default:
|
||||
gesture_binding_execute(seat, binding);
|
||||
break;
|
||||
}
|
||||
gesture_binding_execute(seat, binding);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1160,23 +1117,6 @@ static void handle_rebase(struct sway_seat *seat, uint32_t time_msec) {
|
|||
e->previous_node = node_at_coords(seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
// Reset the swipe if any other button is pressed during the swipe
|
||||
struct sway_workspace *focused_ws = seat_get_focused_workspace(seat);
|
||||
if (focused_ws) {
|
||||
struct sway_output *output = focused_ws->output;
|
||||
struct workspace_scroll workspace_scroll_default = workspace_scroll_get_default();
|
||||
switch (e->gestures.type) {
|
||||
default:
|
||||
break;
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_HORIZONTAL:
|
||||
case GESTURE_TYPE_WORKSPACE_SWIPE_VERTICAL:
|
||||
if (!workspace_scroll_equal(&output->workspace_scroll, &workspace_scroll_default)) {
|
||||
workspace_scroll_reset(seat, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (surface) {
|
||||
if (seat_is_input_allowed(seat, surface)) {
|
||||
wlr_seat_pointer_notify_enter(seat->wlr_seat, surface, sx, sy);
|
||||
|
|
|
@ -24,8 +24,6 @@ sway_sources = files(
|
|||
'desktop/xdg_shell.c',
|
||||
'desktop/launcher.c',
|
||||
|
||||
'fx_util/animation_utils.c',
|
||||
|
||||
'input/input-manager.c',
|
||||
'input/cursor.c',
|
||||
'input/keyboard.c',
|
||||
|
@ -124,7 +122,7 @@ sway_sources = files(
|
|||
'commands/set.c',
|
||||
'commands/shadow_blur_radius.c',
|
||||
'commands/shadow_color.c',
|
||||
'commands/shadow_offset.c',
|
||||
'commands/shadow_offset.c',
|
||||
'commands/shadow_inactive_color.c',
|
||||
'commands/shadows.c',
|
||||
'commands/shadows_on_csd.c',
|
||||
|
@ -146,7 +144,6 @@ sway_sources = files(
|
|||
'commands/unmark.c',
|
||||
'commands/urgent.c',
|
||||
'commands/workspace.c',
|
||||
'commands/workspace_gesture.c',
|
||||
'commands/workspace_layout.c',
|
||||
'commands/ws_auto_back_and_forth.c',
|
||||
'commands/xwayland.c',
|
||||
|
|
|
@ -548,61 +548,6 @@ runtime.
|
|||
|
||||
```
|
||||
|
||||
*bindworkspacegesture* [--input-device=<device>] [--no-warn] \
|
||||
[--inverted] [<fingers>][:direction]
|
||||
Binds the swipe to switch workspaces in a 1:1 fashion, but only when
|
||||
detected. Optionally can be limited to bind to a certain number of
|
||||
_fingers_ or to certain _directions_.
|
||||
|
||||
[[ *type*
|
||||
:[ *fingers*
|
||||
:< *direction*
|
||||
| swipe
|
||||
: 3 - 5
|
||||
: horizontal, vertical
|
||||
|
||||
The _fingers_ can be limited to any sensible number or left empty to accept
|
||||
any finger counts.
|
||||
Valid directions are _horizontal_ and _vertical_.
|
||||
|
||||
If a _input-device_ is given, the binding will only be executed for
|
||||
that input device and will be executed instead of any binding that is
|
||||
generic to all devices. By default, if you overwrite a binding,
|
||||
swaynag will give you a warning. To silence this, use the _--no-warn_ flag.
|
||||
|
||||
If _inverted_ is given, the swipe direction will be reversed.
|
||||
|
||||
The priority for matching bindings is as follows: input device, then
|
||||
exact matches.
|
||||
|
||||
Gestures executed while the pointer is above a bar are not handled by sway.
|
||||
See the respective documentation, e.g. *bindgesture* in *sway-bar*(5).
|
||||
|
||||
Example:
|
||||
```
|
||||
# Allow switching between workspaces with left and right swipes
|
||||
bindworkspacegesture 4:horizontal
|
||||
# Allow switching between workspaces with up and down swipes
|
||||
bindworkspacegesture 3:vertical
|
||||
# Allow switching between workspaces with up and down swipes but inverted
|
||||
bindworkspacegesture --inverted 3:vertical
|
||||
|
||||
```
|
||||
|
||||
*workspace_gesture_spring_size* <value>
|
||||
Adjusts the workspace gestures spring size. Can use values between
|
||||
0 (disabled) and 100 while 50 is the default value.
|
||||
|
||||
*workspace_gesture_wrap_around* <enable|disable>
|
||||
Sets whether or not the workspace gesture should wrap around when trying to
|
||||
swipe past the first/last workspace. Disables the
|
||||
_workspace_gesture_spring_size_ config option. Disabled by default.
|
||||
|
||||
*workspace_gesture_threshold* <value>
|
||||
Adjusts the swipe threshold of switching workspaces. A lower value makes it
|
||||
easier to switch workspaces. Accepts values between 0.1 (small swipes) and
|
||||
0.9 (large swipes). The default value is set to 0.5.
|
||||
|
||||
*client.background* <color>
|
||||
This command is ignored and is only present for i3 compatibility.
|
||||
|
||||
|
|
|
@ -354,11 +354,11 @@ struct sway_workspace *workspace_by_name(const char *name) {
|
|||
if (current && strcmp(name, "prev") == 0) {
|
||||
return workspace_prev(current);
|
||||
} else if (current && strcmp(name, "prev_on_output") == 0) {
|
||||
return workspace_output_prev(current, true);
|
||||
return workspace_output_prev(current);
|
||||
} else if (current && strcmp(name, "next") == 0) {
|
||||
return workspace_next(current);
|
||||
} else if (current && strcmp(name, "next_on_output") == 0) {
|
||||
return workspace_output_next(current, true);
|
||||
return workspace_output_next(current);
|
||||
} else if (strcmp(name, "current") == 0) {
|
||||
return current;
|
||||
} else if (strcasecmp(name, "back_and_forth") == 0) {
|
||||
|
@ -521,7 +521,7 @@ struct sway_workspace *workspace_next(struct sway_workspace *workspace) {
|
|||
* otherwise the next one is returned.
|
||||
*/
|
||||
static struct sway_workspace *workspace_output_prev_next_impl(
|
||||
struct sway_output *output, int dir, bool should_wrap) {
|
||||
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) {
|
||||
|
@ -531,27 +531,17 @@ static struct sway_workspace *workspace_output_prev_next_impl(
|
|||
}
|
||||
|
||||
int index = list_find(output->workspaces, workspace);
|
||||
size_t new_index;
|
||||
if (!should_wrap) {
|
||||
new_index = index += dir;
|
||||
if (index < 0 || index >= output->workspaces->length) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
new_index = wrap(index + dir, output->workspaces->length);
|
||||
}
|
||||
size_t new_index = wrap(index + dir, output->workspaces->length);
|
||||
return output->workspaces->items[new_index];
|
||||
}
|
||||
|
||||
|
||||
struct sway_workspace *workspace_output_next(struct sway_workspace *current,
|
||||
bool should_wrap) {
|
||||
return workspace_output_prev_next_impl(current->output, 1, should_wrap);
|
||||
struct sway_workspace *workspace_output_next(struct sway_workspace *current) {
|
||||
return workspace_output_prev_next_impl(current->output, 1);
|
||||
}
|
||||
|
||||
struct sway_workspace *workspace_output_prev(struct sway_workspace *current,
|
||||
bool should_wrap) {
|
||||
return workspace_output_prev_next_impl(current->output, -1, should_wrap);
|
||||
struct sway_workspace *workspace_output_prev(struct sway_workspace *current) {
|
||||
return workspace_output_prev_next_impl(current->output, -1);
|
||||
}
|
||||
|
||||
struct sway_workspace *workspace_auto_back_and_forth(
|
||||
|
@ -581,7 +571,6 @@ bool workspace_switch(struct sway_workspace *workspace) {
|
|||
|
||||
sway_log(SWAY_DEBUG, "Switching to workspace %p:%s",
|
||||
workspace, workspace->name);
|
||||
workspace->output->workspace_scroll = workspace_scroll_get_default();
|
||||
struct sway_node *next = seat_get_focus_inactive(seat, &workspace->node);
|
||||
if (next == NULL) {
|
||||
next = &workspace->node;
|
||||
|
|
Loading…
Reference in a new issue