Reorganize Tray Code

Remove tray code from bar.c and render.c
This commit is contained in:
Calvin Lee 2017-06-07 21:32:48 -07:00
parent 790887ce76
commit 1451ee8fd1
5 changed files with 152 additions and 123 deletions

View file

@ -2,12 +2,15 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <dbus/dbus.h>
#include "swaybar/bar.h"
#include "swaybar/tray/tray.h"
#include "swaybar/tray/dbus.h"
#include "swaybar/tray/sni.h"
#include "swaybar/tray/sni_watcher.h"
#include "swaybar/bar.h"
#include "swaybar/config.h"
#include "list.h"
#include "log.h"
@ -184,7 +187,7 @@ static DBusHandlerResult signal_handler(DBusConnection *connection,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
int init_tray() {
static int init_host() {
tray = (struct tray *)malloc(sizeof(tray));
tray->items = create_list();
@ -277,3 +280,129 @@ err:
free(name);
return -1;
}
void tray_mouse_event(struct output *output, int x, int y,
uint32_t button, uint32_t state) {
struct window *window = output->window;
uint32_t tray_padding = swaybar.config->tray_padding;
int tray_width = window->width * window->scale;
for (int i = 0; i < output->items->length; ++i) {
struct sni_icon_ref *item =
output->items->items[i];
int icon_width = cairo_image_surface_get_width(item->icon);
tray_width -= tray_padding;
if (x <= tray_width && x >= tray_width - icon_width) {
if (button == swaybar.config->activate_button) {
sni_activate(item->ref, x, y);
} else if (button == swaybar.config->context_button) {
sni_context_menu(item->ref, x, y);
} else if (button == swaybar.config->secondary_button) {
sni_secondary(item->ref, x, y);
}
break;
}
tray_width -= icon_width;
}
}
uint32_t tray_render(struct output *output, struct config *config) {
struct window *window = output->window;
cairo_t *cairo = window->cairo;
// Tray icons
uint32_t tray_padding = config->tray_padding;
uint32_t tray_width = window->width * window->scale;
const int item_size = (window->height * window->scale) - (2 * tray_padding);
if (item_size < 0) {
// Can't render items if the padding is too large
return tray_width;
}
if (config->tray_output && strcmp(config->tray_output, output->name) != 0) {
return tray_width;
}
for (int i = 0; i < tray->items->length; ++i) {
struct StatusNotifierItem *item =
tray->items->items[i];
if (!item->image) {
continue;
}
struct sni_icon_ref *render_item = NULL;
int j;
for (j = i; j < output->items->length; ++j) {
struct sni_icon_ref *ref =
output->items->items[j];
if (ref->ref == item) {
render_item = ref;
break;
} else {
sni_icon_ref_free(ref);
list_del(output->items, j);
}
}
if (!render_item) {
render_item = sni_icon_ref_create(item, item_size);
list_add(output->items, render_item);
} else if (item->dirty) {
// item needs re-render
sni_icon_ref_free(render_item);
output->items->items[j] = render_item =
sni_icon_ref_create(item, item_size);
}
tray_width -= tray_padding;
tray_width -= item_size;
cairo_operator_t op = cairo_get_operator(cairo);
cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
cairo_set_source_surface(cairo, render_item->icon, tray_width, tray_padding);
cairo_rectangle(cairo, tray_width, tray_padding, item_size, item_size);
cairo_fill(cairo);
cairo_set_operator(cairo, op);
item->dirty = false;
}
if (tray_width != window->width * window->scale) {
tray_width -= tray_padding;
}
return tray_width;
}
void tray_upkeep(struct bar *bar) {
if (!bar->xembed_pid ||
(bar->xembed_pid == waitpid(bar->xembed_pid, NULL, WNOHANG))) {
pid_t pid = fork();
if (pid == 0) {
execlp("xembedsniproxy", "xembedsniproxy", NULL);
_exit(EXIT_FAILURE);
} else {
bar->xembed_pid = pid;
}
}
}
void init_tray(struct bar *bar) {
if (!bar->config->tray_output || strcmp(bar->config->tray_output, "none") != 0) {
/* Connect to the D-Bus */
dbus_init();
/* Start the SNI watcher */
init_sni_watcher();
/* Start the SNI host */
init_host();
/* Start xembedsniproxy */
tray_upkeep(bar);
}
}