aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/input.c')
-rw-r--r--swaybar/input.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/swaybar/input.c b/swaybar/input.c
index 6e13f177..ada4bc86 100644
--- a/swaybar/input.c
+++ b/swaybar/input.c
@@ -81,8 +81,16 @@ void update_cursor(struct swaybar_seat *seat) {
81 int scale = pointer->current ? pointer->current->scale : 1; 81 int scale = pointer->current ? pointer->current->scale : 1;
82 pointer->cursor_theme = wl_cursor_theme_load( 82 pointer->cursor_theme = wl_cursor_theme_load(
83 cursor_theme, cursor_size * scale, seat->bar->shm); 83 cursor_theme, cursor_size * scale, seat->bar->shm);
84 if (!pointer->cursor_theme) {
85 sway_log(SWAY_ERROR, "Failed to load cursor theme");
86 return;
87 }
84 struct wl_cursor *cursor; 88 struct wl_cursor *cursor;
85 cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr"); 89 cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "default");
90 if (!cursor) {
91 sway_log(SWAY_ERROR, "Failed to get default cursor from theme");
92 return;
93 }
86 pointer->cursor_image = cursor->images[0]; 94 pointer->cursor_image = cursor->images[0];
87 wl_surface_set_buffer_scale(pointer->cursor_surface, scale); 95 wl_surface_set_buffer_scale(pointer->cursor_surface, scale);
88 wl_surface_attach(pointer->cursor_surface, 96 wl_surface_attach(pointer->cursor_surface,
@@ -103,7 +111,7 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
103 struct swaybar_pointer *pointer = &seat->pointer; 111 struct swaybar_pointer *pointer = &seat->pointer;
104 seat->pointer.x = wl_fixed_to_double(surface_x); 112 seat->pointer.x = wl_fixed_to_double(surface_x);
105 seat->pointer.y = wl_fixed_to_double(surface_y); 113 seat->pointer.y = wl_fixed_to_double(surface_y);
106 pointer->serial = serial; 114
107 struct swaybar_output *output; 115 struct swaybar_output *output;
108 wl_list_for_each(output, &seat->bar->outputs, link) { 116 wl_list_for_each(output, &seat->bar->outputs, link) {
109 if (output->surface == surface) { 117 if (output->surface == surface) {
@@ -111,7 +119,18 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
111 break; 119 break;
112 } 120 }
113 } 121 }
114 update_cursor(seat); 122
123 if (seat->bar->cursor_shape_manager) {
124 struct wp_cursor_shape_device_v1 *device =
125 wp_cursor_shape_manager_v1_get_pointer(
126 seat->bar->cursor_shape_manager, wl_pointer);
127 wp_cursor_shape_device_v1_set_shape(device, serial,
128 WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
129 wp_cursor_shape_device_v1_destroy(device);
130 } else {
131 pointer->serial = serial;
132 update_cursor(seat);
133 }
115} 134}
116 135
117static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, 136static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer,
@@ -141,16 +160,15 @@ static bool check_bindings(struct swaybar *bar, uint32_t button,
141} 160}
142 161
143static bool process_hotspots(struct swaybar_output *output, 162static bool process_hotspots(struct swaybar_output *output,
144 double x, double y, uint32_t button) { 163 double x, double y, uint32_t button, uint32_t state) {
145 double px = x * output->scale; 164 bool released = state == WL_POINTER_BUTTON_STATE_RELEASED;
146 double py = y * output->scale;
147 struct swaybar_hotspot *hotspot; 165 struct swaybar_hotspot *hotspot;
148 wl_list_for_each(hotspot, &output->hotspots, link) { 166 wl_list_for_each(hotspot, &output->hotspots, link) {
149 if (px >= hotspot->x && py >= hotspot->y 167 if (x >= hotspot->x && y >= hotspot->y
150 && px < hotspot->x + hotspot->width 168 && x < hotspot->x + hotspot->width
151 && py < hotspot->y + hotspot->height) { 169 && y < hotspot->y + hotspot->height) {
152 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y, 170 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y,
153 button, hotspot->data)) { 171 button, released, hotspot->data)) {
154 return true; 172 return true;
155 } 173 }
156 } 174 }
@@ -168,14 +186,11 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
168 return; 186 return;
169 } 187 }
170 188
171 if (check_bindings(seat->bar, button, state)) { 189 if (process_hotspots(output, pointer->x, pointer->y, button, state)) {
172 return; 190 return;
173 } 191 }
174 192
175 if (state != WL_POINTER_BUTTON_STATE_PRESSED) { 193 check_bindings(seat->bar, button, state);
176 return;
177 }
178 process_hotspots(output, pointer->x, pointer->y, button);
179} 194}
180 195
181static void workspace_next(struct swaybar *bar, struct swaybar_output *output, 196static void workspace_next(struct swaybar *bar, struct swaybar_output *output,
@@ -211,7 +226,7 @@ static void workspace_next(struct swaybar *bar, struct swaybar_output *output,
211 } 226 }
212 } 227 }
213 228
214 if (new) { 229 if (new && new != active) {
215 ipc_send_workspace_command(bar, new->name); 230 ipc_send_workspace_command(bar, new->name);
216 231
217 // Since we're asking Sway to switch to 'new', it should become visible. 232 // Since we're asking Sway to switch to 'new', it should become visible.
@@ -224,15 +239,15 @@ static void workspace_next(struct swaybar *bar, struct swaybar_output *output,
224static void process_discrete_scroll(struct swaybar_seat *seat, 239static void process_discrete_scroll(struct swaybar_seat *seat,
225 struct swaybar_output *output, struct swaybar_pointer *pointer, 240 struct swaybar_output *output, struct swaybar_pointer *pointer,
226 uint32_t axis, wl_fixed_t value) { 241 uint32_t axis, wl_fixed_t value) {
227 // If there is a button press binding, execute it, skip default behavior,
228 // and check button release bindings
229 uint32_t button = wl_axis_to_button(axis, value); 242 uint32_t button = wl_axis_to_button(axis, value);
230 if (check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_PRESSED)) { 243 if (process_hotspots(output, pointer->x, pointer->y, button, WL_POINTER_BUTTON_STATE_PRESSED)) {
231 check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_RELEASED); 244 // (Currently hotspots don't do anything on release events, so no need to emit one)
232 return; 245 return;
233 } 246 }
234 247
235 if (process_hotspots(output, pointer->x, pointer->y, button)) { 248 // If there is a button press binding, execute it, and check button release bindings
249 if (check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_PRESSED)) {
250 check_bindings(seat->bar, button, WL_POINTER_BUTTON_STATE_RELEASED);
236 return; 251 return;
237 } 252 }
238 253
@@ -405,7 +420,8 @@ static void wl_touch_up(void *data, struct wl_touch *wl_touch,
405 } 420 }
406 if (time - slot->time < 500) { 421 if (time - slot->time < 500) {
407 // Tap, treat it like a pointer click 422 // Tap, treat it like a pointer click
408 process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT); 423 process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
424 // (Currently hotspots don't do anything on release events, so no need to emit one)
409 } 425 }
410 slot->output = NULL; 426 slot->output = NULL;
411} 427}