aboutsummaryrefslogtreecommitdiff
path: root/swaybar
diff options
context:
space:
mode:
authorCalvin Lee <cyrus296@gmail.com>2017-06-07 21:32:48 -0700
committerCalvin Lee <cyrus296@gmail.com>2017-06-07 21:32:48 -0700
commit1451ee8fd13dd35227d11e393c80871c70ad90f0 (patch)
tree74a34de797c46c2734751d77b4dc4ac5694af9a7 /swaybar
parent790887ce762fb51d18e966de22bd2ab5b6a593c7 (diff)
downloadsway-1451ee8fd13dd35227d11e393c80871c70ad90f0.tar.xz
Reorganize Tray Code
Remove tray code from bar.c and render.c
Diffstat (limited to 'swaybar')
-rw-r--r--swaybar/bar.c60
-rw-r--r--swaybar/render.c67
-rw-r--r--swaybar/tray/tray.c131
3 files changed, 139 insertions, 119 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c
index cdaf6a37..5d480b63 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -27,6 +27,9 @@ static void bar_init(struct bar *bar) {
bar->config = init_config();
bar->status = init_status_line();
bar->outputs = create_list();
+#ifdef ENABLE_TRAY
+ bar->xembed_pid = 0;
+#endif
}
static void spawn_status_cmd_proc(struct bar *bar) {
@@ -57,24 +60,6 @@ static void spawn_status_cmd_proc(struct bar *bar) {
}
}
-#ifdef ENABLE_TRAY
-static void spawn_xembed_sni_proxy() {
- pid_t pid = fork();
- if (pid == 0) {
- int wstatus;
- do {
- pid = fork();
- if (pid == 0) {
- execlp("xembedsniproxy", "xembedsniproxy", NULL);
- _exit(EXIT_FAILURE);
- }
- waitpid(pid, &wstatus, 0);
- } while (!WIFEXITED(wstatus));
- _exit(EXIT_FAILURE);
- }
-}
-#endif
-
struct output *new_output(const char *name) {
struct output *output = malloc(sizeof(struct output));
output->name = strdup(name);
@@ -122,27 +107,7 @@ static void mouse_button_notify(struct window *window, int x, int y,
}
#ifdef ENABLE_TRAY
- uint32_t tray_padding = swaybar.config->tray_padding;
- int tray_width = window->width * window->scale;
-
- for (int i = 0; i < clicked_output->items->length; ++i) {
- struct sni_icon_ref *item =
- clicked_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;
- }
+ tray_mouse_event(clicked_output, x, y, button, state_w);
#endif
}
@@ -235,20 +200,7 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) {
spawn_status_cmd_proc(bar);
#ifdef ENABLE_TRAY
- // We should have at least one output to serve the tray to
- if (!swaybar.config->tray_output || strcmp(swaybar.config->tray_output, "none") != 0) {
- /* Connect to the D-Bus */
- dbus_init();
-
- /* Start the SNI watcher */
- init_sni_watcher();
-
- /* Start the SNI host */
- init_tray();
-
- /* Start xembedsniproxy */
- spawn_xembed_sni_proxy();
- }
+ init_tray(bar);
#endif
}
@@ -300,6 +252,8 @@ void bar_run(struct bar *bar) {
event_loop_poll();
#ifdef ENABLE_TRAY
+ tray_upkeep(bar);
+
dispatch_dbus();
#endif
}
diff --git a/swaybar/render.c b/swaybar/render.c
index d02ecbbb..6ec47e79 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -302,72 +302,9 @@ void render(struct output *output, struct config *config, struct status_line *li
cairo_paint(cairo);
#ifdef ENABLE_TRAY
- // Tray icons
- uint32_t tray_padding = config->tray_padding;
- unsigned int 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
- goto no_tray;
- }
-
- if (config->tray_output && strcmp(config->tray_output, output->name) != 0) {
- goto no_tray;
- }
-
- 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;
- }
-
-no_tray:
+ uint32_t tray_width = tray_render(output, config);
#else
- const int tray_width = window->width * window->scale;
+ const uint32_t tray_width = window->width * window->scale;
#endif
// Command output
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c
index 9a709fe4..ca8b1341 100644
--- a/swaybar/tray/tray.c
+++ b/swaybar/tray/tray.c
@@ -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);
+ }
+}