aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/input.c')
-rw-r--r--swaybar/input.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/swaybar/input.c b/swaybar/input.c
index c8c8f0d4..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,14 +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) {
164 bool released = state == WL_POINTER_BUTTON_STATE_RELEASED;
145 struct swaybar_hotspot *hotspot; 165 struct swaybar_hotspot *hotspot;
146 wl_list_for_each(hotspot, &output->hotspots, link) { 166 wl_list_for_each(hotspot, &output->hotspots, link) {
147 if (x >= hotspot->x && y >= hotspot->y 167 if (x >= hotspot->x && y >= hotspot->y
148 && x < hotspot->x + hotspot->width 168 && x < hotspot->x + hotspot->width
149 && y < hotspot->y + hotspot->height) { 169 && y < hotspot->y + hotspot->height) {
150 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y, 170 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y,
151 button, hotspot->data)) { 171 button, released, hotspot->data)) {
152 return true; 172 return true;
153 } 173 }
154 } 174 }
@@ -166,14 +186,11 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
166 return; 186 return;
167 } 187 }
168 188
169 if (check_bindings(seat->bar, button, state)) { 189 if (process_hotspots(output, pointer->x, pointer->y, button, state)) {
170 return; 190 return;
171 } 191 }
172 192
173 if (state != WL_POINTER_BUTTON_STATE_PRESSED) { 193 check_bindings(seat->bar, button, state);
174 return;
175 }
176 process_hotspots(output, pointer->x, pointer->y, button);
177} 194}
178 195
179static void workspace_next(struct swaybar *bar, struct swaybar_output *output, 196static void workspace_next(struct swaybar *bar, struct swaybar_output *output,
@@ -209,7 +226,7 @@ static void workspace_next(struct swaybar *bar, struct swaybar_output *output,
209 } 226 }
210 } 227 }
211 228
212 if (new) { 229 if (new && new != active) {
213 ipc_send_workspace_command(bar, new->name); 230 ipc_send_workspace_command(bar, new->name);
214 231
215 // 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.
@@ -222,15 +239,15 @@ static void workspace_next(struct swaybar *bar, struct swaybar_output *output,
222static void process_discrete_scroll(struct swaybar_seat *seat, 239static void process_discrete_scroll(struct swaybar_seat *seat,
223 struct swaybar_output *output, struct swaybar_pointer *pointer, 240 struct swaybar_output *output, struct swaybar_pointer *pointer,
224 uint32_t axis, wl_fixed_t value) { 241 uint32_t axis, wl_fixed_t value) {
225 // If there is a button press binding, execute it, skip default behavior,
226 // and check button release bindings
227 uint32_t button = wl_axis_to_button(axis, value); 242 uint32_t button = wl_axis_to_button(axis, value);
228 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)) {
229 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)
230 return; 245 return;
231 } 246 }
232 247
233 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);
234 return; 251 return;
235 } 252 }
236 253
@@ -403,7 +420,8 @@ static void wl_touch_up(void *data, struct wl_touch *wl_touch,
403 } 420 }
404 if (time - slot->time < 500) { 421 if (time - slot->time < 500) {
405 // Tap, treat it like a pointer click 422 // Tap, treat it like a pointer click
406 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)
407 } 425 }
408 slot->output = NULL; 426 slot->output = NULL;
409} 427}