Skip to content

Commit

Permalink
swaybar: implement mouse events for tray
Browse files Browse the repository at this point in the history
  • Loading branch information
ianyfan committed Dec 7, 2018
1 parent fa3ce83 commit 3628df5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/swaybar/bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ struct swaybar_output {
struct pool_buffer *current_buffer;
bool dirty;
bool frame_scheduled;

uint32_t output_height, output_width, output_x, output_y;
};

struct swaybar_workspace {
Expand Down
8 changes: 6 additions & 2 deletions swaybar/bar.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,16 @@ struct wl_output_listener output_listener = {

static void xdg_output_handle_logical_position(void *data,
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,
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,
Expand Down
61 changes: 61 additions & 0 deletions swaybar/tray/item_kde.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
#include <string.h>
#include "swaybar/bar.h"
#include "swaybar/config.h"
#include "swaybar/input.h"
#include "swaybar/tray/host_kde.h"
#include "swaybar/tray/icon.h"
#include "swaybar/tray/item_kde.h"
#include "swaybar/tray/tray.h"
#include "background-image.h"
#include "cairo.h"
#include "log.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h"

static char *interface = "org.kde.StatusNotifierItem";

Expand Down Expand Up @@ -132,6 +134,55 @@ void destroy_sni_kde(struct swaybar_sni_kde *sni) {
free(sni);
}

static void sni_handle_click(struct swaybar_sni_kde *sni, int x, int y, enum x11_button button) {
sd_bus *bus = sni->tray->bus;

char *method;
switch (button) {
case LEFT: method = sni->item_is_menu ? "ContextMenu" : "Activate"; break;
case RIGHT: method = "ContextMenu"; break;
case MIDDLE: method = "SecondaryActivate"; break;
default: method = NULL;
}

if (method) {
sd_bus_error error = SD_BUS_ERROR_NULL;
// Remember: "is" for scroll
int ret = sd_bus_call_method(bus, sni->service, sni->path, interface,
method, &error, NULL, "ii", x, y);
if (ret < 0) {
wlr_log(WLR_DEBUG, "Failed to click button: %s", error.message);
sd_bus_error_free(&error);
}
}
}

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 sni %s", (char *)data);

struct swaybar_tray *tray = output->bar->tray;
struct swaybar_host_kde *host_kde = tray->host_kde;

for (int i = 0; i < host_kde->items->length; ++i) {
struct swaybar_sni_kde *sni = host_kde->items->items[i];
if (strcmp(sni->dbus_id, data) == 0) {
// guess actual position since wayland doesn't expose it
// output pos + output dimensions + position + bar gaps
int global_x = output->output_x + x;
int global_y = output->output_y + (output->bar->config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP ? y : (int) output->output_height - y);

wlr_log(WLR_DEBUG, "Guessing click at %d %d", global_x, global_y);

sni_handle_click(sni, global_x, global_y, button);
return HOTSPOT_IGNORE;
}
}

return HOTSPOT_PROCESS;
}

uint32_t render_sni_kde(cairo_t *cairo, struct swaybar_output *output,
double *x, struct swaybar_sni_kde *sni) {
uint32_t height = output->height * output->scale;
Expand Down Expand Up @@ -174,5 +225,15 @@ uint32_t render_sni_kde(cairo_t *cairo, struct swaybar_output *output,

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->dbus_id);
wl_list_insert(&output->hotspots, &hotspot->link);

return output->height;
}

0 comments on commit 3628df5

Please sign in to comment.