Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Tray Icons #1234

Merged
merged 8 commits into from
Jun 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions CMake/FindDBus.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# - Try to find DBus
# Once done, this will define
#
# DBUS_FOUND - system has DBus
# DBUS_INCLUDE_DIRS - the DBus include directories
# DBUS_LIBRARIES - link these to use DBus
#
# Copyright (C) 2012 Raphael Kubo da Costa <[email protected]>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_DBUS QUIET dbus-1)

FIND_LIBRARY(DBUS_LIBRARIES
NAMES dbus-1
HINTS ${PC_DBUS_LIBDIR}
${PC_DBUS_LIBRARY_DIRS}
)

FIND_PATH(DBUS_INCLUDE_DIR
NAMES dbus/dbus.h
HINTS ${PC_DBUS_INCLUDEDIR}
${PC_DBUS_INCLUDE_DIRS}
)

GET_FILENAME_COMPONENT(_DBUS_LIBRARY_DIR ${DBUS_LIBRARIES} PATH)
FIND_PATH(DBUS_ARCH_INCLUDE_DIR
NAMES dbus/dbus-arch-deps.h
HINTS ${PC_DBUS_INCLUDEDIR}
${PC_DBUS_INCLUDE_DIRS}
${_DBUS_LIBRARY_DIR}
${DBUS_INCLUDE_DIR}
PATH_SUFFIXES include
)

SET(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})

INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DBUS REQUIRED_VARS DBUS_INCLUDE_DIRS DBUS_LIBRARIES)
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ option(enable-swaybar "Enables the swaybar utility" YES)
option(enable-swaygrab "Enables the swaygrab utility" YES)
option(enable-swaymsg "Enables the swaymsg utility" YES)
option(enable-gdk-pixbuf "Use Pixbuf to support more image formats" YES)
option(enable-tray "Enables the swaybar tray" YES)
option(zsh-completions "Zsh shell completions" NO)
option(default-wallpaper "Installs the default wallpaper" YES)
option(LD_LIBRARY_PATH "Configure sway's default LD_LIBRARY_PATH")
Expand All @@ -64,6 +65,7 @@ find_package(Cairo REQUIRED)
find_package(Pango REQUIRED)
find_package(GdkPixbuf)
find_package(PAM)
find_package(DBus)

find_package(LibInput REQUIRED)

Expand All @@ -90,6 +92,17 @@ else()
message(STATUS "Building without gdk-pixbuf, only png images supported.")
endif()

if (enable-tray)
if (DBUS_FOUND)
set(ENABLE_TRAY)
add_definitions(-DENABLE_TRAY)
else()
message(WARNING "Tray required but DBus was not found. Tray will not be included")
endif()
else()
message(STATUS "Building without the tray.")
endif()

include_directories(include)

add_subdirectory(protocols)
Expand Down
2 changes: 2 additions & 0 deletions include/client/cairo.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

void cairo_set_source_u32(cairo_t *cairo, uint32_t color);

cairo_surface_t *cairo_image_surface_scale(cairo_surface_t *image, int width, int height);

#ifdef WITH_GDK_PIXBUF
#include <gdk-pixbuf/gdk-pixbuf.h>

Expand Down
4 changes: 4 additions & 0 deletions include/sway/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,21 @@ sway_cmd cmd_workspace;
sway_cmd cmd_ws_auto_back_and_forth;
sway_cmd cmd_workspace_layout;

sway_cmd bar_cmd_activate_button;
sway_cmd bar_cmd_binding_mode_indicator;
sway_cmd bar_cmd_bindsym;
sway_cmd bar_cmd_colors;
sway_cmd bar_cmd_context_button;
sway_cmd bar_cmd_font;
sway_cmd bar_cmd_mode;
sway_cmd bar_cmd_modifier;
sway_cmd bar_cmd_output;
sway_cmd bar_cmd_height;
sway_cmd bar_cmd_hidden_state;
sway_cmd bar_cmd_icon_theme;
sway_cmd bar_cmd_id;
sway_cmd bar_cmd_position;
sway_cmd bar_cmd_secondary_button;
sway_cmd bar_cmd_separator_symbol;
sway_cmd bar_cmd_status_command;
sway_cmd bar_cmd_pango_markup;
Expand Down
12 changes: 11 additions & 1 deletion include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,17 @@ struct bar_config {
char *swaybar_command;
char *font;
int height; // -1 not defined
int tray_padding;

#ifdef ENABLE_TRAY
// Tray
char *tray_output;
char *icon_theme;
uint32_t tray_padding;
uint32_t activate_button;
uint32_t context_button;
uint32_t secondary_button;
#endif

bool workspace_buttons;
bool wrap_scroll;
char *separator_symbol;
Expand Down
6 changes: 6 additions & 0 deletions include/swaybar/bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ struct output {
struct window *window;
struct registry *registry;
list_t *workspaces;
#ifdef ENABLE_TRAY
list_t *items;
#endif
char *name;
int idx;
bool focused;
Expand All @@ -37,6 +40,9 @@ struct workspace {
/** Global bar state */
extern struct bar swaybar;

/** True if sway needs to render */
extern bool dirty;

/**
* Setup bar.
*/
Expand Down
11 changes: 11 additions & 0 deletions include/swaybar/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ struct config {
bool all_outputs;
list_t *outputs;

#ifdef ENABLE_TRAY
// Tray
char *tray_output;
char *icon_theme;

uint32_t tray_padding;
uint32_t activate_button;
uint32_t context_button;
uint32_t secondary_button;
#endif

int height;

struct {
Expand Down
26 changes: 26 additions & 0 deletions include/swaybar/event_loop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _SWAYBAR_EVENT_LOOP_H
#define _SWAYBAR_EVENT_LOOP_H

#include <stdbool.h>
#include <time.h>

void add_event(int fd, short mask,
void(*cb)(int fd, short mask, void *data),
void *data);

// Not guaranteed to notify cb immediately
void add_timer(timer_t timer,
void(*cb)(timer_t timer, void *data),
void *data);

// Returns false if nothing exists, true otherwise
bool remove_event(int fd);

// Returns false if nothing exists, true otherwise
bool remove_timer(timer_t timer);

// Blocks and returns after sending callbacks
void event_loop_poll();

void init_event_loop();
#endif /*_SWAYBAR_EVENT_LOOP_H */
18 changes: 18 additions & 0 deletions include/swaybar/tray/dbus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef _SWAYBAR_DBUS_H
#define _SWAYBAR_DBUS_H

#include <stdbool.h>
#include <dbus/dbus.h>
extern DBusConnection *conn;

/**
* Should be called in main loop to dispatch events
*/
void dispatch_dbus();

/**
* Initializes async dbus communication
*/
int dbus_init();

#endif /* _SWAYBAR_DBUS_H */
16 changes: 16 additions & 0 deletions include/swaybar/tray/icon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef _SWAYBAR_ICON_H
#define _SWAYBAR_ICON_H

#include <stdint.h>
#include <stdbool.h>
#include <client/cairo.h>

/**
* Returns the image found by `name` that is closest to `size`
*/
cairo_surface_t *find_icon(const char *name, int size);

/* Struct used internally only */
struct subdir;

#endif /* _SWAYBAR_ICON_H */
81 changes: 81 additions & 0 deletions include/swaybar/tray/sni.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef _SWAYBAR_SNI_H
#define _SWAYBAR_SNI_H

#include <stdbool.h>
#include <client/cairo.h>

struct StatusNotifierItem {
/* Name registered to sni watcher */
char *name;
/* Unique bus name, needed for determining signal origins */
char *unique_name;
bool kde_special_snowflake;

cairo_surface_t *image;
bool dirty;
};

/* Each output holds an sni_icon_ref of each item to render */
struct sni_icon_ref {
cairo_surface_t *icon;
struct StatusNotifierItem *ref;
};

struct sni_icon_ref *sni_icon_ref_create(struct StatusNotifierItem *item,
int height);

void sni_icon_ref_free(struct sni_icon_ref *sni_ref);

/**
* Will return a new item and get its icon. (see warning below)
*/
struct StatusNotifierItem *sni_create(const char *name);

/**
* `item` must be a struct StatusNotifierItem *
* `str` must be a NUL terminated char *
*
* Returns 0 if `item` has a name of `str`
*/
int sni_str_cmp(const void *item, const void *str);

/**
* Returns 0 if `item` has a unique name of `str` or if
* `item->unique_name == NULL`
*/
int sni_uniq_cmp(const void *item, const void *str);

/**
* Gets an icon for the given item if found.
*
* XXX
* This function keeps a reference to the item until it gets responses, make
* sure that the reference and item are valid during this time.
*/
void get_icon(struct StatusNotifierItem *item);

/**
* Calls the "activate" method on the given StatusNotifierItem
*
* x and y should be where the item was clicked
*/
void sni_activate(struct StatusNotifierItem *item, uint32_t x, uint32_t y);

/**
* Asks the item to draw a context menu at the given x and y coords
*/
void sni_context_menu(struct StatusNotifierItem *item, uint32_t x, uint32_t y);

/**
* Calls the "secondary activate" method on the given StatusNotifierItem
*
* x and y should be where the item was clicked
*/
void sni_secondary(struct StatusNotifierItem *item, uint32_t x, uint32_t y);

/**
* Deconstructs `item`
*/
void sni_free(struct StatusNotifierItem *item);

#endif /* _SWAYBAR_SNI_H */
10 changes: 10 additions & 0 deletions include/swaybar/tray/sni_watcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _SWAYBAR_SNI_WATCHER_H
#define _SWAYBAR_SNI_WATCHER_H

/**
* Starts the sni_watcher, the watcher is practically a black box and should
* only be accessed though functions described in its spec
*/
int init_sni_watcher();

#endif /* _SWAYBAR_SNI_WATCHER_H */
32 changes: 32 additions & 0 deletions include/swaybar/tray/tray.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef _SWAYBAR_TRAY_H
#define _SWAYBAR_TRAY_H

#include <stdint.h>
#include <stdbool.h>
#include "swaybar/tray/dbus.h"
#include "swaybar/tray/sni.h"
#include "swaybar/bar.h"
#include "list.h"

extern struct tray *tray;

struct tray {
list_t *items;
};

/**
* Processes a mouse event on the bar
*/
void tray_mouse_event(struct output *output, int x, int y,
uint32_t button, uint32_t state);

uint32_t tray_render(struct output *output, struct config *config);

void tray_upkeep(struct bar *bar);

/**
* Initializes the tray with D-Bus
*/
void init_tray();

#endif /* _SWAYBAR_TRAY_H */
4 changes: 4 additions & 0 deletions sway/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,18 +221,22 @@ static struct cmd_handler handlers[] = {
};

static struct cmd_handler bar_handlers[] = {
{ "activate_button", bar_cmd_activate_button },
{ "binding_mode_indicator", bar_cmd_binding_mode_indicator },
{ "bindsym", bar_cmd_bindsym },
{ "colors", bar_cmd_colors },
{ "context_button", bar_cmd_context_button },
{ "font", bar_cmd_font },
{ "height", bar_cmd_height },
{ "hidden_state", bar_cmd_hidden_state },
{ "icon_theme", bar_cmd_icon_theme },
{ "id", bar_cmd_id },
{ "mode", bar_cmd_mode },
{ "modifier", bar_cmd_modifier },
{ "output", bar_cmd_output },
{ "pango_markup", bar_cmd_pango_markup },
{ "position", bar_cmd_position },
{ "secondary_button", bar_cmd_secondary_button },
{ "separator_symbol", bar_cmd_separator_symbol },
{ "status_command", bar_cmd_status_command },
{ "strip_workspace_numbers", bar_cmd_strip_workspace_numbers },
Expand Down
Loading