aboutsummaryrefslogtreecommitdiff
path: root/sway/input/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/cursor.c')
-rw-r--r--sway/input/cursor.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 96feb47d..9af7ef57 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -2,8 +2,10 @@
#include <math.h>
#include <libevdev/libevdev.h>
#include <linux/input-event-codes.h>
+#include <errno.h>
#include <float.h>
#include <limits.h>
+#include <strings.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_idle.h>
@@ -85,6 +87,10 @@ static struct sway_node *node_at_coords(
return NULL;
}
struct sway_output *output = wlr_output->data;
+ if (!output) {
+ // output is being destroyed
+ return NULL;
+ }
double ox = lx, oy = ly;
wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);
@@ -1092,6 +1098,8 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor,
enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE;
bool on_border = edge != WLR_EDGE_NONE;
bool on_titlebar = cont && !on_border && !surface;
+ bool on_titlebar_border = cont && on_border &&
+ cursor->cursor->y < cont->content_y;
bool on_contents = cont && !on_border && surface;
float scroll_factor =
(ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor;
@@ -1117,7 +1125,7 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor,
}
// Scrolling on a tabbed or stacked title bar (handled as press event)
- if (!handled && on_titlebar) {
+ if (!handled && (on_titlebar || on_titlebar_border)) {
enum sway_container_layout layout = container_parent_layout(cont);
if (layout == L_TABBED || layout == L_STACKED) {
struct sway_node *tabcontainer = node_get_parent(node);
@@ -1527,3 +1535,66 @@ void cursor_warp_to_workspace(struct sway_cursor *cursor,
wlr_cursor_warp(cursor->cursor, NULL, x, y);
}
+
+uint32_t get_mouse_bindsym(const char *name, char **error) {
+ if (strncasecmp(name, "button", strlen("button")) == 0) {
+ // Map to x11 mouse buttons
+ int number = name[strlen("button")] - '0';
+ if (number < 1 || number > 9 || strlen(name) > strlen("button0")) {
+ *error = strdup("Only buttons 1-9 are supported. For other mouse "
+ "buttons, use the name of the event code.");
+ return 0;
+ }
+ static const uint32_t buttons[] = {BTN_LEFT, BTN_MIDDLE, BTN_RIGHT,
+ SWAY_SCROLL_UP, SWAY_SCROLL_DOWN, SWAY_SCROLL_LEFT,
+ SWAY_SCROLL_RIGHT, BTN_SIDE, BTN_EXTRA};
+ return buttons[number - 1];
+ } else if (strncmp(name, "BTN_", strlen("BTN_")) == 0) {
+ // Get event code from name
+ int code = libevdev_event_code_from_name(EV_KEY, name);
+ if (code == -1) {
+ size_t len = snprintf(NULL, 0, "Unknown event %s", name) + 1;
+ *error = malloc(len);
+ if (*error) {
+ snprintf(*error, len, "Unknown event %s", name);
+ }
+ return 0;
+ }
+ return code;
+ }
+ return 0;
+}
+
+uint32_t get_mouse_bindcode(const char *name, char **error) {
+ // Validate event code
+ errno = 0;
+ char *endptr;
+ int code = strtol(name, &endptr, 10);
+ if (endptr == name && code <= 0) {
+ *error = strdup("Button event code must be a positive integer.");
+ return 0;
+ } else if (errno == ERANGE) {
+ *error = strdup("Button event code out of range.");
+ return 0;
+ }
+ const char *event = libevdev_event_code_get_name(EV_KEY, code);
+ if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
+ size_t len = snprintf(NULL, 0, "Event code %d (%s) is not a button",
+ code, event) + 1;
+ *error = malloc(len);
+ if (*error) {
+ snprintf(*error, len, "Event code %d (%s) is not a button",
+ code, event);
+ }
+ return 0;
+ }
+ return code;
+}
+
+uint32_t get_mouse_button(const char *name, char **error) {
+ uint32_t button = get_mouse_bindsym(name, error);
+ if (!button && !error) {
+ button = get_mouse_bindcode(name, error);
+ }
+ return button;
+}