mirror of
https://github.com/swaywm/sway.git
synced 2024-11-04 15:33:13 +00:00
swaybar: implement mouse events for tray
This commit is contained in:
parent
fa2c5282c1
commit
6becde0246
|
@ -70,6 +70,8 @@ struct swaybar_output {
|
||||||
struct pool_buffer *current_buffer;
|
struct pool_buffer *current_buffer;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
bool frame_scheduled;
|
bool frame_scheduled;
|
||||||
|
|
||||||
|
uint32_t output_height, output_width, output_x, output_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct swaybar_workspace {
|
struct swaybar_workspace {
|
||||||
|
|
|
@ -215,12 +215,16 @@ struct wl_output_listener output_listener = {
|
||||||
|
|
||||||
static void xdg_output_handle_logical_position(void *data,
|
static void xdg_output_handle_logical_position(void *data,
|
||||||
struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) {
|
struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) {
|
||||||
// Who cares
|
struct swaybar_output *output = data;
|
||||||
|
output->output_x = x;
|
||||||
|
output->output_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_output_handle_logical_size(void *data,
|
static void xdg_output_handle_logical_size(void *data,
|
||||||
struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) {
|
struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height) {
|
||||||
// Who cares
|
struct swaybar_output *output = data;
|
||||||
|
output->output_height = height;
|
||||||
|
output->output_width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_output_handle_done(void *data,
|
static void xdg_output_handle_done(void *data,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "swaybar/bar.h"
|
#include "swaybar/bar.h"
|
||||||
#include "swaybar/config.h"
|
#include "swaybar/config.h"
|
||||||
|
#include "swaybar/input.h"
|
||||||
#include "swaybar/tray/host.h"
|
#include "swaybar/tray/host.h"
|
||||||
#include "swaybar/tray/icon.h"
|
#include "swaybar/tray/icon.h"
|
||||||
#include "swaybar/tray/item.h"
|
#include "swaybar/tray/item.h"
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
// TODO menu
|
// TODO menu
|
||||||
|
|
||||||
|
@ -248,6 +250,83 @@ void destroy_sni(struct swaybar_sni *sni) {
|
||||||
free(sni);
|
free(sni);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_click(struct swaybar_sni *sni, int x, int y,
|
||||||
|
enum x11_button button, int delta) {
|
||||||
|
const char *method = sni->tray->bar->config->tray_bindings[button];
|
||||||
|
if (!method) {
|
||||||
|
static const char *default_bindings[10] = {
|
||||||
|
"nop",
|
||||||
|
"Activate",
|
||||||
|
"SecondaryActivate",
|
||||||
|
"ContextMenu",
|
||||||
|
"ScrollUp",
|
||||||
|
"ScrollDown",
|
||||||
|
"ScrollLeft",
|
||||||
|
"ScrollRight",
|
||||||
|
"nop",
|
||||||
|
"nop"
|
||||||
|
};
|
||||||
|
method = default_bindings[button];
|
||||||
|
}
|
||||||
|
if (strcmp(method, "nop") == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sni->item_is_menu && strcmp(method, "Activate") == 0) {
|
||||||
|
method = "ContextMenu";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(method, "Scroll", strlen("Scroll")) == 0) {
|
||||||
|
char dir = method[strlen("Scroll")];
|
||||||
|
char *orientation = (dir = 'U' || dir == 'D') ? "vertical" : "horizontal";
|
||||||
|
int sign = (dir == 'U' || dir == 'L') ? -1 : 1;
|
||||||
|
|
||||||
|
int ret = sd_bus_call_method_async(sni->tray->bus, NULL, sni->service,
|
||||||
|
sni->path, sni->interface, "Scroll", NULL, NULL, "is",
|
||||||
|
delta*sign, orientation);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_DEBUG, "Failed to scroll on SNI: %s", strerror(-ret));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int ret = sd_bus_call_method_async(sni->tray->bus, NULL, sni->service,
|
||||||
|
sni->path, sni->interface, method, NULL, NULL, "ii", x, y);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_DEBUG, "Failed to click on SNI: %s", strerror(-ret));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmp_sni_id(const void *item, const void *cmp_to) {
|
||||||
|
const struct swaybar_sni *sni = item;
|
||||||
|
return strcmp(sni->watcher_id, cmp_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum hotspot_event_handling icon_hotspot_callback(
|
||||||
|
struct swaybar_output *output, struct swaybar_hotspot *hotspot,
|
||||||
|
int x, int y, enum x11_button button, void *data) {
|
||||||
|
wlr_log(WLR_DEBUG, "Clicked on Status Notifier Item '%s'", (char *)data);
|
||||||
|
|
||||||
|
struct swaybar_tray *tray = output->bar->tray;
|
||||||
|
int idx = list_seq_find(tray->items, cmp_sni_id, data);
|
||||||
|
|
||||||
|
if (idx != -1) {
|
||||||
|
struct swaybar_sni *sni = tray->items->items[idx];
|
||||||
|
// guess global position since wayland doesn't expose it
|
||||||
|
struct swaybar_config *config = tray->bar->config;
|
||||||
|
int global_x = output->output_x + config->gaps.left + x;
|
||||||
|
bool top_bar = config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||||
|
int global_y = output->output_y + (top_bar ? config->gaps.top + y:
|
||||||
|
(int) output->output_height - config->gaps.bottom - y);
|
||||||
|
|
||||||
|
wlr_log(WLR_DEBUG, "Guessing click at (%d, %d)", global_x, global_y);
|
||||||
|
handle_click(sni, global_x, global_y, button, 1); // TODO get delta from event
|
||||||
|
return HOTSPOT_IGNORE;
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_DEBUG, "but it doesn't exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
return HOTSPOT_PROCESS;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
|
uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
|
||||||
struct swaybar_sni *sni) {
|
struct swaybar_sni *sni) {
|
||||||
uint32_t height = output->height * output->scale;
|
uint32_t height = output->height * output->scale;
|
||||||
|
@ -316,5 +395,15 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
|
||||||
|
|
||||||
cairo_surface_destroy(icon);
|
cairo_surface_destroy(icon);
|
||||||
|
|
||||||
|
struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
|
||||||
|
hotspot->x = *x;
|
||||||
|
hotspot->y = 0;
|
||||||
|
hotspot->width = height;
|
||||||
|
hotspot->height = height;
|
||||||
|
hotspot->callback = icon_hotspot_callback;
|
||||||
|
hotspot->destroy = free;
|
||||||
|
hotspot->data = strdup(sni->watcher_id);
|
||||||
|
wl_list_insert(&output->hotspots, &hotspot->link);
|
||||||
|
|
||||||
return output->height;
|
return output->height;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue