summaryrefslogtreecommitdiff
path: root/swaybar/render.c
diff options
context:
space:
mode:
authorCalvin Lee <[email protected]>2017-06-07 16:45:28 -0700
committerCalvin Lee <[email protected]>2017-06-07 17:49:16 -0700
commit843ad38b3c427adb0bf319e9613d9813c8d9246c (patch)
treee02a5b06e2b6923371fd53724791c147c18a1fa4 /swaybar/render.c
parentfd47a30e75cccfc3789eafa4bfabd66f4696099b (diff)
Implement Tray Icons
This commit implements the StatusNotifierItem protocol, and enables swaybar to show tray icons. It also uses `xembedsniproxy` in order to communicate with xembed applications. The tray is completely optional, and can be disabled on compile time with the `enable-tray` option. Or on runtime with the bar config option `tray_output none`. Overview of changes: In swaybar very little is changed outside the tray subfolder except that all events are now polled in `event_loop.c`, this creates no functional difference. Six bar configuration options were added, these are detailed in sway-bar(5) The tray subfolder is where all protocol implementation takes place and is organised as follows: tray/sni_watcher.c: This file contains the StatusNotifierWatcher. It keeps track of items and hosts and reports when they come or go. tray/tray.c This file contains the StatusNotifierHost. It keeps track of sway's version of the items and represents the tray itself. tray/sni.c This file contains the StatusNotifierItem struct and all communication with individual items. tray/icon.c This file implements the icon theme protocol. It allows for finding icons by name, rather than by pixmap. tray/dbus.c This file allows for asynchronous DBus communication. See #986 #343
Diffstat (limited to 'swaybar/render.c')
-rw-r--r--swaybar/render.c75
1 files changed, 72 insertions, 3 deletions
diff --git a/swaybar/render.c b/swaybar/render.c
index 2eae997f..0b2ac438 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -8,6 +8,10 @@
#include "swaybar/config.h"
#include "swaybar/status_line.h"
#include "swaybar/render.h"
+#ifdef ENABLE_TRAY
+#include "swaybar/tray/tray.h"
+#include "swaybar/tray/sni.h"
+#endif
#include "log.h"
@@ -297,6 +301,72 @@ 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_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);
+
+ item->dirty = false;
+ }
+
+
+ if (tray_width != window->width * window->scale) {
+ tray_width -= tray_padding;
+ }
+
+no_tray:
+#else
+ const int tray_width = window->width * window->scale;
+#endif
+
// Command output
if (is_focused) {
cairo_set_source_u32(cairo, config->colors.focused_statusline);
@@ -309,12 +379,11 @@ void render(struct output *output, struct config *config, struct status_line *li
if (line->protocol == TEXT) {
get_text_size(window->cairo, window->font, &width, &height,
window->scale, config->pango_markup, "%s", line->text_line);
- cairo_move_to(cairo, (window->width * window->scale)
- - margin - width, margin);
+ cairo_move_to(cairo, tray_width - margin - width, margin);
pango_printf(window->cairo, window->font, window->scale,
config->pango_markup, "%s", line->text_line);
} else if (line->protocol == I3BAR && line->block_line) {
- double pos = (window->width * window->scale) - 0.5;
+ double pos = tray_width - 0.5;
bool edge = true;
for (i = line->block_line->length - 1; i >= 0; --i) {
struct status_block *block = line->block_line->items[i];