summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2017-06-14 18:53:32 -0400
committerGitHub <noreply@github.com>2017-06-14 18:53:32 -0400
commiteb6e38c86d2deb37cc6f378f8644c4a530fd7448 (patch)
treee3c567c4684faf0f9a7f77494f1bf638171d5349
parent16e20ec251b027c5a8dbc5e85804012f2602629d (diff)
parent0fc9628f03984caa04e200a1dc458d1cf7fc6d6c (diff)
Merge pull request #1234 from 4e554c4c/tray
Implement Tray Icons
-rw-r--r--CMake/FindDBus.cmake59
-rw-r--r--CMakeLists.txt13
-rw-r--r--include/client/cairo.h2
-rw-r--r--include/sway/commands.h4
-rw-r--r--include/sway/config.h12
-rw-r--r--include/swaybar/bar.h6
-rw-r--r--include/swaybar/config.h11
-rw-r--r--include/swaybar/event_loop.h26
-rw-r--r--include/swaybar/tray/dbus.h18
-rw-r--r--include/swaybar/tray/icon.h16
-rw-r--r--include/swaybar/tray/sni.h81
-rw-r--r--include/swaybar/tray/sni_watcher.h10
-rw-r--r--include/swaybar/tray/tray.h32
-rw-r--r--sway/commands.c4
-rw-r--r--sway/commands/bar/activate_button.c26
-rw-r--r--sway/commands/bar/context_button.c26
-rw-r--r--sway/commands/bar/icon_theme.c25
-rw-r--r--sway/commands/bar/secondary_button.c26
-rw-r--r--sway/commands/bar/tray_output.c26
-rw-r--r--sway/commands/bar/tray_padding.c34
-rw-r--r--sway/config.c11
-rw-r--r--sway/container.c17
-rw-r--r--sway/handlers.c2
-rw-r--r--sway/ipc-json.c17
-rw-r--r--sway/sway-bar.5.txt36
-rw-r--r--swaybar/CMakeLists.txt11
-rw-r--r--swaybar/bar.c84
-rw-r--r--swaybar/config.c12
-rw-r--r--swaybar/event_loop.c143
-rw-r--r--swaybar/ipc.c40
-rw-r--r--swaybar/render.c15
-rw-r--r--swaybar/tray/dbus.c189
-rw-r--r--swaybar/tray/icon.c404
-rw-r--r--swaybar/tray/sni.c471
-rw-r--r--swaybar/tray/sni_watcher.c487
-rw-r--r--swaybar/tray/tray.c393
-rw-r--r--wayland/cairo.c19
37 files changed, 2747 insertions, 61 deletions
diff --git a/CMake/FindDBus.cmake b/CMake/FindDBus.cmake
new file mode 100644
index 00000000..4a1a1805
--- /dev/null
+++ b/CMake/FindDBus.cmake
@@ -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 <rakuco@webkit.org>
+#
+# 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)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index edf486ca..c80f6361 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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")
@@ -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)
@@ -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)
diff --git a/include/client/cairo.h b/include/client/cairo.h
index 46c53566..e7ef7c7e 100644
--- a/include/client/cairo.h
+++ b/include/client/cairo.h
@@ -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>
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 078652e7..f67df10f 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -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;
diff --git a/include/sway/config.h b/include/sway/config.h
index 35f8d5f7..999a471a 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -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;
diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h
index 697a48c2..010e1f84 100644
--- a/include/swaybar/bar.h
+++ b/include/swaybar/bar.h
@@ -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;
@@ -37,6 +40,9 @@ struct workspace {
/** Global bar state */
extern struct bar swaybar;
+/** True if sway needs to render */
+extern bool dirty;
+
/**
* Setup bar.
*/
diff --git a/include/swaybar/config.h b/include/swaybar/config.h
index 04b12cd4..651f0ee3 100644
--- a/include/swaybar/config.h
+++ b/include/swaybar/config.h
@@ -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 {
diff --git a/include/swaybar/event_loop.h b/include/swaybar/event_loop.h
new file mode 100644
index 00000000..a0cde07f
--- /dev/null
+++ b/include/swaybar/event_loop.h
@@ -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 */
diff --git a/include/swaybar/tray/dbus.h b/include/swaybar/tray/dbus.h
new file mode 100644
index 00000000..eb9cfea7
--- /dev/null
+++ b/include/swaybar/tray/dbus.h
@@ -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 */
diff --git a/include/swaybar/tray/icon.h b/include/swaybar/tray/icon.h
new file mode 100644
index 00000000..1cc6ff9c
--- /dev/null
+++ b/include/swaybar/tray/icon.h
@@ -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 */
diff --git a/include/swaybar/tray/sni.h b/include/swaybar/tray/sni.h
new file mode 100644
index 00000000..83809b2d
--- /dev/null
+++ b/include/swaybar/tray/sni.h
@@ -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 */
diff --git a/include/swaybar/tray/sni_watcher.h b/include/swaybar/tray/sni_watcher.h
new file mode 100644
index 00000000..25ddfcd2
--- /dev/null
+++ b/include/swaybar/tray/sni_watcher.h
@@ -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 */
diff --git a/include/swaybar/tray/tray.h b/include/swaybar/tray/tray.h
new file mode 100644
index 00000000..b718e555
--- /dev/null
+++ b/include/swaybar/tray/tray.h
@@ -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 */
diff --git a/sway/commands.c b/sway/commands.c
index 34218491..f83b5287 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -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 },
diff --git a/sway/commands/bar/activate_button.c b/sway/commands/bar/activate_button.c
new file mode 100644
index 00000000..32a1d3e5
--- /dev/null
+++ b/sway/commands/bar/activate_button.c
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include "sway/commands.h"
+#include "log.h"
+
+struct cmd_results *bar_cmd_activate_button(int argc, char **argv) {
+ const char *cmd_name = "activate_button";
+#ifndef ENABLE_TRAY
+ return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
+ "%s called, but sway was compiled without tray support",
+ cmd_name, cmd_name);
+#else
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+
+ if (!config->current_bar) {
+ return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
+ }
+
+ // User should be able to prefix with 0x or whatever they want
+ config->current_bar->secondary_button = strtoul(argv[0], NULL, 0);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+#endif
+}
diff --git a/sway/commands/bar/context_button.c b/sway/commands/bar/context_button.c
new file mode 100644
index 00000000..6d7d7aec
--- /dev/null
+++ b/sway/commands/bar/context_button.c
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include "sway/commands.h"
+#include "log.h"
+
+struct cmd_results *bar_cmd_context_button(int argc, char **argv) {
+ const char *cmd_name = "context_button";
+#ifndef ENABLE_TRAY
+ return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
+ "%s called, but sway was compiled without tray support",
+ cmd_name, cmd_name);
+#else
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+
+ if (!config->current_bar) {
+ return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
+ }
+
+ // User should be able to prefix with 0x or whatever they want
+ config->current_bar->context_button = strtoul(argv[0], NULL, 0);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+#endif
+}
diff --git a/sway/commands/bar/icon_theme.c b/sway/commands/bar/icon_theme.c
new file mode 100644
index 00000000..cbfc0be5
--- /dev/null
+++ b/sway/commands/bar/icon_theme.c
@@ -0,0 +1,25 @@
+#define _XOPEN_SOURCE 500
+#include <string.h>
+#include "sway/commands.h"
+
+struct cmd_results *bar_cmd_icon_theme(int argc, char **argv) {
+ const char *cmd_name = "tray_output";
+#ifndef ENABLE_TRAY
+ return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
+ "%s called, but sway was compiled without tray support",
+ cmd_name, cmd_name);
+#else
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+
+ if (!config->current_bar) {
+ return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
+ }
+
+ config->current_bar->icon_theme = strdup(argv[0]);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+#endif
+}
diff --git a/sway/commands/bar/secondary_button.c b/sway/commands/bar/secondary_button.c
new file mode 100644
index 00000000..745045c5
--- /dev/null
+++ b/sway/commands/bar/secondary_button.c
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include "sway/commands.h"
+#include "log.h"
+
+struct cmd_results *bar_cmd_secondary_button(int argc, char **argv) {
+ const char *cmd_name = "secondary_button";
+#ifndef ENABLE_TRAY
+ return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
+ "%s called, but sway was compiled without tray support",
+ cmd_name, cmd_name);
+#else
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+
+ if (!config->current_bar) {
+ return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
+ }
+
+ // User should be able to prefix with 0x or whatever they want
+ config->current_bar->secondary_button = strtoul(argv[0], NULL, 0);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+#endif
+}
diff --git a/sway/commands/bar/tray_output.c b/sway/commands/bar/tray_output.c
index 8a1b5d35..012304a9 100644
--- a/sway/commands/bar/tray_output.c
+++ b/sway/commands/bar/tray_output.c
@@ -1,7 +1,29 @@
+#define _XOPEN_SOURCE 500
+#include <string.h>
#include "sway/commands.h"
-#include "log.h"
struct cmd_results *bar_cmd_tray_output(int argc, char **argv) {
- sway_log(L_ERROR, "Warning: tray_output is not supported on wayland");
+ const char *cmd_name = "tray_output";
+#ifndef ENABLE_TRAY
+ return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
+ "%s called, but sway was compiled without tray support",
+ cmd_name, cmd_name);
+#else
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+
+ if (!config->current_bar) {
+ return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
+ }
+
+ if (strcmp(argv[0], "all") == 0) {
+ // Default behaviour
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+ }
+ config->current_bar->tray_output = strdup(argv[0]);
+
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+#endif
}
diff --git a/sway/commands/bar/tray_padding.c b/sway/commands/bar/tray_padding.c
index 8c559f65..ac0572ce 100644
--- a/sway/commands/bar/tray_padding.c
+++ b/sway/commands/bar/tray_padding.c
@@ -1,30 +1,34 @@
#include <stdlib.h>
-#include <string.h>
#include <strings.h>
#include "sway/commands.h"
#include "log.h"
struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) {
+ const char *cmd_name = "tray_padding";
+#ifndef ENABLE_TRAY
+ return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command"
+ "%s called, but sway was compiled without tray support",
+ cmd_name, cmd_name);
+#else
struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "tray_padding", EXPECTED_AT_LEAST, 1))) {
+ if ((error = checkarg(argc, cmd_name, EXPECTED_AT_LEAST, 1))) {
return error;
}
if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "tray_padding", "No bar defined.");
+ return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
}
- int padding = atoi(argv[0]);
- if (padding < 0) {
- return cmd_results_new(CMD_INVALID, "tray_padding",
- "Invalid padding value %s, minimum is 0", argv[0]);
+ if (argc == 1 || (argc == 2 && strcasecmp("px", argv[1]) == 0)) {
+ char *inv;
+ uint32_t padding = strtoul(argv[0], &inv, 10);
+ if (*inv == '\0' || strcasecmp(inv, "px") == 0) {
+ config->current_bar->tray_padding = padding;
+ sway_log(L_DEBUG, "Enabling tray padding of %d px on bar: %s", padding, config->current_bar->id);
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+ }
}
-
- if (argc > 1 && strcasecmp("px", argv[1]) != 0) {
- return cmd_results_new(CMD_INVALID, "tray_padding",
- "Unknown unit %s", argv[1]);
- }
- config->current_bar->tray_padding = padding;
- sway_log(L_DEBUG, "Enabling tray padding of %d px on bar: %s", padding, config->current_bar->id);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+ return cmd_results_new(CMD_FAILURE, cmd_name,
+ "Expected 'tray_padding <padding>[px]'");
+#endif
}
diff --git a/sway/config.c b/sway/config.c
index 85823953..e0b65615 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -69,6 +69,10 @@ static void free_bar(struct bar_config *bar) {
}
free(bar->mode);
free(bar->hidden_state);
+#ifdef ENABLE_TRAY
+ free(bar->tray_output);
+ free(bar->icon_theme);
+#endif
free(bar->status_command);
free(bar->font);
free(bar->separator_symbol);
@@ -1386,7 +1390,14 @@ struct bar_config *default_bar_config(void) {
bar->separator_symbol = NULL;
bar->strip_workspace_numbers = false;
bar->binding_mode_indicator = true;
+#ifdef ENABLE_TRAY
+ bar->tray_output = NULL;
+ bar->icon_theme = NULL;
bar->tray_padding = 2;
+ bar->activate_button = 0x110; /* BTN_LEFT */
+ bar->context_button = 0x111; /* BTN_RIGHT */
+ bar->secondary_button = 0x112; /* BTN_MIDDLE */
+#endif
bar->verbose = false;
bar->pid = 0;
// set default colors
diff --git a/sway/container.c b/sway/container.c
index 08aa77a8..358ba767 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -699,12 +699,12 @@ static bool pointer_test(swayc_t *view, void *_origin) {
swayc_t *container_under_pointer(void) {
// root.output->workspace
- if (!root_container.focused || !root_container.focused->focused) {
+ if (!root_container.focused) {
return NULL;
}
- swayc_t *lookup = root_container.focused->focused;
+ swayc_t *lookup = root_container.focused;
// Case of empty workspace
- if (lookup->children == 0) {
+ if (lookup->children && !lookup->unmanaged) {
return NULL;
}
struct wlc_point origin;
@@ -712,6 +712,17 @@ swayc_t *container_under_pointer(void) {
while (lookup && lookup->type != C_VIEW) {
int i;
int len;
+ for (int _i = 0; lookup->unmanaged && _i < lookup->unmanaged->length; ++_i) {
+ wlc_handle *handle = lookup->unmanaged->items[_i];
+ const struct wlc_geometry *geo = wlc_view_get_geometry(*handle);
+ if (origin.x >= geo->origin.x && origin.y >= geo->origin.y
+ && origin.x < geo->origin.x + (int)geo->size.w
+ && origin.y < geo->origin.y + (int)geo->size.h) {
+ // Hack: we force focus upon unmanaged views here
+ wlc_view_focus(*handle);
+ return NULL;
+ }
+ }
// if tabbed/stacked go directly to focused container, otherwise search
// children
if (lookup->layout == L_TABBED || lookup->layout == L_STACKED) {
diff --git a/sway/handlers.c b/sway/handlers.c
index e1b90a07..a912b991 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -599,6 +599,8 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
view->y = geometry->origin.y;
update_geometry(view);
}
+ } else {
+ wlc_view_set_geometry(handle, 0, geometry);
}
}
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index 512144a4..31de53f0 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -327,7 +327,22 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
json_object *json = json_object_new_object();
json_object_object_add(json, "id", json_object_new_string(bar->id));
- json_object_object_add(json, "tray_output", NULL);
+#ifdef ENABLE_TRAY
+ if (bar->tray_output) {
+ json_object_object_add(json, "tray_output", json_object_new_string(bar->tray_output));
+ } else {
+ json_object_object_add(json, "tray_output", NULL);
+ }
+ if (bar->icon_theme) {
+ json_object_object_add(json, "icon_theme", json_object_new_string(bar->icon_theme));
+ } else {
+ json_object_object_add(json, "icon_theme", NULL);
+ }
+ json_object_object_add(json, "tray_padding", json_object_new_int(bar->tray_padding));
+ json_object_object_add(json, "activate_button", json_object_new_int(bar->activate_button));
+ json_object_object_add(json, "context_button", json_object_new_int(bar->context_button));
+ json_object_object_add(json, "secondary_button", json_object_new_int(bar->secondary_button));
+#endif
json_object_object_add(json, "mode", json_object_new_string(bar->mode));
json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state));
json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier)));
diff --git a/sway/sway-bar.5.txt b/sway/sway-bar.5.txt
index 5a52e7db..29487662 100644
--- a/