diff --git a/include/swaybar/i3bar.h b/include/swaybar/i3bar.h index 0b3bee21..df8cdd09 100644 --- a/include/swaybar/i3bar.h +++ b/include/swaybar/i3bar.h @@ -28,7 +28,7 @@ struct i3bar_block { void i3bar_block_unref(struct i3bar_block *block); bool i3bar_handle_readable(struct status_line *status); enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, - struct i3bar_block *block, int x, int y, int rx, int ry, int w, int h, - uint32_t button); + struct i3bar_block *block, double x, double y, double rx, double ry, + double w, double h, int scale, uint32_t button); #endif diff --git a/include/swaybar/input.h b/include/swaybar/input.h index 6557a29e..65e49218 100644 --- a/include/swaybar/input.h +++ b/include/swaybar/input.h @@ -44,7 +44,7 @@ struct swaybar_hotspot { struct wl_list link; // swaybar_output::hotspots int x, y, width, height; enum hotspot_event_handling (*callback)(struct swaybar_output *output, - struct swaybar_hotspot *hotspot, int x, int y, uint32_t button, + struct swaybar_hotspot *hotspot, double x, double y, uint32_t button, void *data); void (*destroy)(void *data); void *data; diff --git a/include/swaybar/status_line.h b/include/swaybar/status_line.h index 3601a11e..65c3a796 100644 --- a/include/swaybar/status_line.h +++ b/include/swaybar/status_line.h @@ -28,6 +28,7 @@ struct status_line { int cont_signal; bool click_events; + bool float_event_coords; bool clicked; char *buffer; size_t buffer_size; diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c index 5c8b87a2..4bcd5843 100644 --- a/swaybar/i3bar.c +++ b/swaybar/i3bar.c @@ -267,8 +267,8 @@ bool i3bar_handle_readable(struct status_line *status) { } enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, - struct i3bar_block *block, int x, int y, int rx, int ry, int w, int h, - uint32_t button) { + struct i3bar_block *block, double x, double y, double rx, double ry, + double w, double h, int scale, uint32_t button) { sway_log(SWAY_DEBUG, "block %s clicked", block->name); if (!block->name || !status->click_events) { return HOTSPOT_PROCESS; @@ -285,12 +285,22 @@ enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, json_object_object_add(event_json, "button", json_object_new_int(event_to_x11_button(button))); json_object_object_add(event_json, "event", json_object_new_int(button)); - json_object_object_add(event_json, "x", json_object_new_int(x)); - json_object_object_add(event_json, "y", json_object_new_int(y)); - json_object_object_add(event_json, "relative_x", json_object_new_int(rx)); - json_object_object_add(event_json, "relative_y", json_object_new_int(ry)); - json_object_object_add(event_json, "width", json_object_new_int(w)); - json_object_object_add(event_json, "height", json_object_new_int(h)); + if (status->float_event_coords) { + json_object_object_add(event_json, "x", json_object_new_double(x)); + json_object_object_add(event_json, "y", json_object_new_double(y)); + json_object_object_add(event_json, "relative_x", json_object_new_double(rx)); + json_object_object_add(event_json, "relative_y", json_object_new_double(ry)); + json_object_object_add(event_json, "width", json_object_new_double(w)); + json_object_object_add(event_json, "height", json_object_new_double(h)); + } else { + json_object_object_add(event_json, "x", json_object_new_int(x)); + json_object_object_add(event_json, "y", json_object_new_int(y)); + json_object_object_add(event_json, "relative_x", json_object_new_int(rx)); + json_object_object_add(event_json, "relative_y", json_object_new_int(ry)); + json_object_object_add(event_json, "width", json_object_new_int(w)); + json_object_object_add(event_json, "height", json_object_new_int(h)); + } + json_object_object_add(event_json, "scale", json_object_new_int(scale)); if (dprintf(status->write_fd, "%s%s\n", status->clicked ? "," : "", json_object_to_json_string(event_json)) < 0) { status_error(status, "[failed to write click event]"); diff --git a/swaybar/input.c b/swaybar/input.c index aa6290fa..c0352300 100644 --- a/swaybar/input.c +++ b/swaybar/input.c @@ -138,21 +138,23 @@ static bool check_bindings(struct swaybar *bar, uint32_t button, return false; } -static void process_hotspots(struct swaybar_output *output, +static bool process_hotspots(struct swaybar_output *output, double x, double y, uint32_t button) { - x *= output->scale; - y *= output->scale; + double px = x * output->scale; + double py = y * output->scale; struct swaybar_hotspot *hotspot; wl_list_for_each(hotspot, &output->hotspots, link) { - if (x >= hotspot->x && y >= hotspot->y - && x < hotspot->x + hotspot->width - && y < hotspot->y + hotspot->height) { - if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, - x / output->scale, y / output->scale, button, hotspot->data)) { - return; + if (px >= hotspot->x && py >= hotspot->y + && px < hotspot->x + hotspot->width + && py < hotspot->y + hotspot->height) { + if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y, + button, hotspot->data)) { + return true; } } } + + return false; } static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, @@ -229,19 +231,8 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, return; } - struct swaybar_hotspot *hotspot; - wl_list_for_each(hotspot, &output->hotspots, link) { - double x = pointer->x * output->scale; - double y = pointer->y * output->scale; - if (x >= hotspot->x - && y >= hotspot->y - && x < hotspot->x + hotspot->width - && y < hotspot->y + hotspot->height) { - if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, - pointer->x, pointer->y, button, hotspot->data)) { - return; - } - } + if (process_hotspots(output, pointer->x, pointer->y, button)) { + return; } struct swaybar_config *config = seat->bar->config; diff --git a/swaybar/render.c b/swaybar/render.c index 06efb53c..ea5faef6 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -131,11 +131,15 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color, static enum hotspot_event_handling block_hotspot_callback( struct swaybar_output *output, struct swaybar_hotspot *hotspot, - int x, int y, uint32_t button, void *data) { + double x, double y, uint32_t button, void *data) { struct i3bar_block *block = data; struct status_line *status = output->bar->status; - return i3bar_block_send_click(status, block, x, y, x - hotspot->x, - y - hotspot->y, hotspot->width, hotspot->height, button); + return i3bar_block_send_click(status, block, x, y, + x - (double)hotspot->x / output->scale, + y - (double)hotspot->y / output->scale, + (double)hotspot->width / output->scale, + (double)hotspot->height / output->scale, + output->scale, button); } static void i3bar_block_unref_callback(void *data) { @@ -540,7 +544,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, static enum hotspot_event_handling workspace_hotspot_callback( struct swaybar_output *output, struct swaybar_hotspot *hotspot, - int x, int y, uint32_t button, void *data) { + double x, double y, uint32_t button, void *data) { if (button != BTN_LEFT) { return HOTSPOT_PROCESS; } diff --git a/swaybar/status_line.c b/swaybar/status_line.c index 2a9e1da8..fb9271f8 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c @@ -85,6 +85,13 @@ bool status_handle_readable(struct status_line *status) { } } + json_object *float_event_coords; + if (json_object_object_get_ex(header, "float_event_coords", &float_event_coords) + && json_object_get_boolean(float_event_coords)) { + sway_log(SWAY_DEBUG, "Enabling floating-point coordinates."); + status->float_event_coords = true; + } + json_object *signal; if (json_object_object_get_ex(header, "stop_signal", &signal)) { status->stop_signal = json_object_get_int(signal); diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c index 06a8e5b0..b4238417 100644 --- a/swaybar/tray/item.c +++ b/swaybar/tray/item.c @@ -377,7 +377,7 @@ static int cmp_sni_id(const void *item, const void *cmp_to) { static enum hotspot_event_handling icon_hotspot_callback( struct swaybar_output *output, struct swaybar_hotspot *hotspot, - int x, int y, uint32_t button, void *data) { + double x, double y, uint32_t button, void *data) { sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data); struct swaybar_tray *tray = output->bar->tray;