swaybar: implement tray config

This commit is contained in:
Ian Fan 2018-12-09 15:10:41 +00:00
parent 74655f835a
commit 6b03c68775
18 changed files with 271 additions and 55 deletions

View file

@ -182,11 +182,9 @@ sway_cmd cmd_workspace;
sway_cmd cmd_ws_auto_back_and_forth; sway_cmd cmd_ws_auto_back_and_forth;
sway_cmd cmd_workspace_layout; sway_cmd cmd_workspace_layout;
sway_cmd bar_cmd_activate_button;
sway_cmd bar_cmd_binding_mode_indicator; sway_cmd bar_cmd_binding_mode_indicator;
sway_cmd bar_cmd_bindsym; sway_cmd bar_cmd_bindsym;
sway_cmd bar_cmd_colors; sway_cmd bar_cmd_colors;
sway_cmd bar_cmd_context_button;
sway_cmd bar_cmd_font; sway_cmd bar_cmd_font;
sway_cmd bar_cmd_gaps; sway_cmd bar_cmd_gaps;
sway_cmd bar_cmd_mode; sway_cmd bar_cmd_mode;
@ -197,13 +195,13 @@ sway_cmd bar_cmd_hidden_state;
sway_cmd bar_cmd_icon_theme; sway_cmd bar_cmd_icon_theme;
sway_cmd bar_cmd_id; sway_cmd bar_cmd_id;
sway_cmd bar_cmd_position; sway_cmd bar_cmd_position;
sway_cmd bar_cmd_secondary_button;
sway_cmd bar_cmd_separator_symbol; sway_cmd bar_cmd_separator_symbol;
sway_cmd bar_cmd_status_command; sway_cmd bar_cmd_status_command;
sway_cmd bar_cmd_pango_markup; sway_cmd bar_cmd_pango_markup;
sway_cmd bar_cmd_strip_workspace_numbers; sway_cmd bar_cmd_strip_workspace_numbers;
sway_cmd bar_cmd_strip_workspace_name; sway_cmd bar_cmd_strip_workspace_name;
sway_cmd bar_cmd_swaybar_command; sway_cmd bar_cmd_swaybar_command;
sway_cmd bar_cmd_tray_bindsym;
sway_cmd bar_cmd_tray_output; sway_cmd bar_cmd_tray_output;
sway_cmd bar_cmd_tray_padding; sway_cmd bar_cmd_tray_padding;
sway_cmd bar_cmd_wrap_scroll; sway_cmd bar_cmd_wrap_scroll;

View file

@ -6,6 +6,7 @@
#include <time.h> #include <time.h>
#include <wlr/types/wlr_box.h> #include <wlr/types/wlr_box.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include "../include/config.h"
#include "list.h" #include "list.h"
#include "swaynag.h" #include "swaynag.h"
#include "tree/container.h" #include "tree/container.h"
@ -253,6 +254,13 @@ struct bar_config {
char *binding_mode_bg; char *binding_mode_bg;
char *binding_mode_text; char *binding_mode_text;
} colors; } colors;
#if HAVE_TRAY
char *icon_theme;
const char *tray_bindings[10]; // mouse buttons 0-9
list_t *tray_outputs; // char *
int tray_padding;
#endif
}; };
struct bar_binding { struct bar_binding {

View file

@ -3,6 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <wayland-client.h> #include <wayland-client.h>
#include "../include/config.h"
#include "list.h" #include "list.h"
#include "util.h" #include "util.h"
@ -64,6 +65,13 @@ struct swaybar_config {
struct box_colors urgent_workspace; struct box_colors urgent_workspace;
struct box_colors binding_mode; struct box_colors binding_mode;
} colors; } colors;
#if HAVE_TRAY
char *icon_theme;
char *tray_bindings[10]; // mouse buttons 0-9
list_t *tray_outputs; // char *
int tray_padding;
#endif
}; };
struct swaybar_config *init_config(void); struct swaybar_config *init_config(void);

View file

@ -8,11 +8,9 @@
// Must be in alphabetical order for bsearch // Must be in alphabetical order for bsearch
static struct cmd_handler bar_handlers[] = { static struct cmd_handler bar_handlers[] = {
{ "activate_button", bar_cmd_activate_button },
{ "binding_mode_indicator", bar_cmd_binding_mode_indicator }, { "binding_mode_indicator", bar_cmd_binding_mode_indicator },
{ "bindsym", bar_cmd_bindsym }, { "bindsym", bar_cmd_bindsym },
{ "colors", bar_cmd_colors }, { "colors", bar_cmd_colors },
{ "context_button", bar_cmd_context_button },
{ "font", bar_cmd_font }, { "font", bar_cmd_font },
{ "gaps", bar_cmd_gaps }, { "gaps", bar_cmd_gaps },
{ "height", bar_cmd_height }, { "height", bar_cmd_height },
@ -23,11 +21,11 @@ static struct cmd_handler bar_handlers[] = {
{ "output", bar_cmd_output }, { "output", bar_cmd_output },
{ "pango_markup", bar_cmd_pango_markup }, { "pango_markup", bar_cmd_pango_markup },
{ "position", bar_cmd_position }, { "position", bar_cmd_position },
{ "secondary_button", bar_cmd_secondary_button },
{ "separator_symbol", bar_cmd_separator_symbol }, { "separator_symbol", bar_cmd_separator_symbol },
{ "status_command", bar_cmd_status_command }, { "status_command", bar_cmd_status_command },
{ "strip_workspace_name", bar_cmd_strip_workspace_name }, { "strip_workspace_name", bar_cmd_strip_workspace_name },
{ "strip_workspace_numbers", bar_cmd_strip_workspace_numbers }, { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers },
{ "tray_bindsym", bar_cmd_tray_bindsym },
{ "tray_output", bar_cmd_tray_output }, { "tray_output", bar_cmd_tray_output },
{ "tray_padding", bar_cmd_tray_padding }, { "tray_padding", bar_cmd_tray_padding },
{ "workspace_buttons", bar_cmd_workspace_buttons }, { "workspace_buttons", bar_cmd_workspace_buttons },

View file

@ -1,8 +0,0 @@
#include <stdlib.h>
#include "sway/commands.h"
#include "log.h"
struct cmd_results *bar_cmd_activate_button(int argc, char **argv) {
// TODO TRAY
return cmd_results_new(CMD_INVALID, "activate_button", "TODO TRAY");
}

View file

@ -1,8 +0,0 @@
#include <stdlib.h>
#include "sway/commands.h"
#include "log.h"
struct cmd_results *bar_cmd_context_button(int argc, char **argv) {
// TODO TRAY
return cmd_results_new(CMD_INVALID, "context_button", "TODO TRAY");
}

View file

@ -1,7 +1,28 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h> #include <string.h>
#include "config.h"
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h"
#include "log.h"
struct cmd_results *bar_cmd_icon_theme(int argc, char **argv) { struct cmd_results *bar_cmd_icon_theme(int argc, char **argv) {
// TODO TRAY #if HAVE_TRAY
return cmd_results_new(CMD_INVALID, "icon_theme", "TODO TRAY"); struct cmd_results *error = NULL;
if ((error = checkarg(argc, "icon_theme", EXPECTED_EQUAL_TO, 1))) {
return error;
}
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "tray_padding", "No bar defined.");
}
wlr_log(WLR_DEBUG, "[Bar %s] Setting icon theme to %s",
config->current_bar->id, argv[0]);
free(config->current_bar->icon_theme);
config->current_bar->icon_theme = strdup(argv[0]);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
#else
return cmd_results_new(CMD_INVALID, "icon_theme",
"Sway has been compiled without tray support");
#endif
} }

View file

@ -1,8 +0,0 @@
#include <stdlib.h>
#include "sway/commands.h"
#include "log.h"
struct cmd_results *bar_cmd_secondary_button(int argc, char **argv) {
// TODO TRAY
return cmd_results_new(CMD_INVALID, "secondary_button", "TODO TRAY");
}

View file

@ -0,0 +1,55 @@
#include <strings.h>
#include "config.h"
#include "sway/commands.h"
#include "sway/config.h"
#include "log.h"
struct cmd_results *bar_cmd_tray_bindsym(int argc, char **argv) {
#if HAVE_TRAY
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "tray_bindsym", EXPECTED_EQUAL_TO, 2))) {
return error;
}
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "tray_bindsym", "No bar defined.");
}
int button = 0;
if (strncasecmp(argv[0], "button", strlen("button")) == 0 &&
strlen(argv[0]) == strlen("button0")) {
button = argv[0][strlen("button")] - '0';
}
if (button < 1 || button > 9) {
return cmd_results_new(CMD_FAILURE, "tray_bindsym",
"[Bar %s] Only buttons 1 to 9 are supported",
config->current_bar->id);
}
static const char *commands[] = {
"ContextMenu",
"Activate",
"SecondaryActivate",
"ScrollDown",
"ScrollLeft",
"ScrollRight",
"ScrollUp",
"nop"
};
for (size_t i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i) {
if (strcasecmp(argv[1], commands[i]) == 0) {
wlr_log(WLR_DEBUG, "[Bar %s] Binding button %d to %s",
config->current_bar->id, button, commands[i]);
config->current_bar->tray_bindings[button] = commands[i];
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
}
return cmd_results_new(CMD_INVALID, "tray_bindsym",
"[Bar %s] Invalid command %s", config->current_bar->id, argv[1]);
#else
return cmd_results_new(CMD_INVALID, "tray_bindsym",
"Sway has been compiled without tray support");
#endif
}

View file

@ -1,7 +1,42 @@
#define _POSIX_C_SOURCE 200809L
#include <string.h> #include <string.h>
#include "config.h"
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h"
#include "list.h"
#include "log.h"
struct cmd_results *bar_cmd_tray_output(int argc, char **argv) { struct cmd_results *bar_cmd_tray_output(int argc, char **argv) {
// TODO TRAY #if HAVE_TRAY
return cmd_results_new(CMD_INVALID, "tray_output", "TODO TRAY"); struct cmd_results *error = NULL;
if ((error = checkarg(argc, "tray_output", EXPECTED_EQUAL_TO, 1))) {
return error;
}
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "tray_output", "No bar defined.");
}
list_t *outputs = config->current_bar->tray_outputs;
if (!outputs) {
config->current_bar->tray_outputs = outputs = create_list();
}
if (strcmp(argv[0], "none") == 0) {
wlr_log(WLR_DEBUG, "Hiding tray on bar: %s", config->current_bar->id);
for (int i = 0; i < outputs->length; ++i) {
free(outputs->items[i]);
}
outputs->length = 0;
} else {
wlr_log(WLR_DEBUG, "Showing tray on output '%s' for bar: %s", argv[0],
config->current_bar->id);
list_add(outputs, strdup(argv[0]));
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
#else
return cmd_results_new(CMD_INVALID, "tray_output",
"Sway has been compiled without tray support");
#endif
} }

View file

@ -1,9 +1,42 @@
#include <stdlib.h> #include <stdlib.h>
#include <strings.h> #include <strings.h>
#include "config.h"
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h"
#include "log.h" #include "log.h"
struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) {
// TODO TRAY #if HAVE_TRAY
return cmd_results_new(CMD_INVALID, "tray_padding", "TODO TRAY"); struct cmd_results *error = NULL;
if ((error = checkarg(argc, "tray_padding", EXPECTED_AT_LEAST, 1))) {
return error;
}
if ((error = checkarg(argc, "tray_padding", EXPECTED_AT_MOST, 2))) {
return error;
}
if (!config->current_bar) {
return cmd_results_new(CMD_FAILURE, "tray_padding", "No bar defined.");
}
struct bar_config *bar = config->current_bar;
char *end;
int padding = strtol(argv[0], &end, 10);
if (padding < 0 || (*end != '\0' && strcasecmp(end, "px") != 0)) {
return cmd_results_new(CMD_INVALID, "tray_padding",
"[Bar %s] Invalid tray padding value: %s", bar->id, argv[0]);
}
if (argc == 2 && strcasecmp(argv[1], "px") != 0) {
return cmd_results_new(CMD_INVALID, "tray_padding",
"Expected 'tray_padding <px> [px]'");
}
wlr_log(WLR_DEBUG, "[Bar %s] Setting tray padding to %d", bar->id, padding);
config->current_bar->tray_padding = padding;
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
#else
return cmd_results_new(CMD_INVALID, "tray_padding",
"Sway has been compiled without tray support");
#endif
} }

View file

@ -12,6 +12,7 @@
#include <signal.h> #include <signal.h>
#include "sway/config.h" #include "sway/config.h"
#include "sway/output.h" #include "sway/output.h"
#include "config.h"
#include "stringop.h" #include "stringop.h"
#include "list.h" #include "list.h"
#include "log.h" #include "log.h"
@ -77,6 +78,10 @@ void free_bar_config(struct bar_config *bar) {
free(bar->colors.binding_mode_border); free(bar->colors.binding_mode_border);
free(bar->colors.binding_mode_bg); free(bar->colors.binding_mode_bg);
free(bar->colors.binding_mode_text); free(bar->colors.binding_mode_text);
#if HAVE_TRAY
list_free_items_and_destroy(bar->tray_outputs);
free(bar->icon_theme);
#endif
free(bar); free(bar);
} }
@ -165,6 +170,10 @@ struct bar_config *default_bar_config(void) {
bar->colors.binding_mode_bg = NULL; bar->colors.binding_mode_bg = NULL;
bar->colors.binding_mode_text = NULL; bar->colors.binding_mode_text = NULL;
#if HAVE_TRAY
bar->tray_padding = 2;
#endif
list_add(config->bars, bar); list_add(config->bars, bar);
return bar; return bar;
cleanup: cleanup:

View file

@ -1,6 +1,7 @@
#include <json-c/json.h> #include <json-c/json.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include "config.h"
#include "log.h" #include "log.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/ipc-json.h" #include "sway/ipc-json.h"
@ -785,5 +786,41 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
} }
json_object_object_add(json, "outputs", outputs); json_object_object_add(json, "outputs", outputs);
} }
#if HAVE_TRAY
// Add tray outputs if defined
if (bar->tray_outputs && bar->tray_outputs->length > 0) {
json_object *tray_outputs = json_object_new_array();
for (int i = 0; i < bar->tray_outputs->length; ++i) {
const char *name = bar->tray_outputs->items[i];
json_object_array_add(tray_outputs, json_object_new_string(name));
}
json_object_object_add(json, "tray_outputs", tray_outputs);
}
json_object *tray_bindings = json_object_new_array();
for (int i = 0; i < 10; ++i) {
if (bar->tray_bindings[i]) {
json_object *bind = json_object_new_object();
json_object_object_add(bind, "input_code",
json_object_new_int(i));
json_object_object_add(bind, "command",
json_object_new_string(bar->tray_bindings[i]));
json_object_array_add(tray_bindings, bind);
}
}
if (json_object_array_length(tray_bindings) > 0) {
json_object_object_add(json, "tray_bindings", tray_bindings);
} else {
json_object_put(tray_bindings);
}
if (bar->icon_theme) {
json_object_object_add(json, "icon_theme",
json_object_new_string(bar->icon_theme));
}
json_object_object_add(json, "tray_padding",
json_object_new_int(bar->tray_padding));
#endif
return json; return json;
} }

View file

@ -99,11 +99,9 @@ sway_sources = files(
'commands/workspace_layout.c', 'commands/workspace_layout.c',
'commands/ws_auto_back_and_forth.c', 'commands/ws_auto_back_and_forth.c',
'commands/bar/activate_button.c',
'commands/bar/binding_mode_indicator.c', 'commands/bar/binding_mode_indicator.c',
'commands/bar/bindsym.c', 'commands/bar/bindsym.c',
'commands/bar/colors.c', 'commands/bar/colors.c',
'commands/bar/context_button.c',
'commands/bar/font.c', 'commands/bar/font.c',
'commands/bar/gaps.c', 'commands/bar/gaps.c',
'commands/bar/height.c', 'commands/bar/height.c',
@ -115,12 +113,12 @@ sway_sources = files(
'commands/bar/output.c', 'commands/bar/output.c',
'commands/bar/pango_markup.c', 'commands/bar/pango_markup.c',
'commands/bar/position.c', 'commands/bar/position.c',
'commands/bar/secondary_button.c',
'commands/bar/separator_symbol.c', 'commands/bar/separator_symbol.c',
'commands/bar/status_command.c', 'commands/bar/status_command.c',
'commands/bar/strip_workspace_numbers.c', 'commands/bar/strip_workspace_numbers.c',
'commands/bar/strip_workspace_name.c', 'commands/bar/strip_workspace_name.c',
'commands/bar/swaybar_command.c', 'commands/bar/swaybar_command.c',
'commands/bar/tray_bindsym.c',
'commands/bar/tray_output.c', 'commands/bar/tray_output.c',
'commands/bar/tray_padding.c', 'commands/bar/tray_padding.c',
'commands/bar/workspace_buttons.c', 'commands/bar/workspace_buttons.c',

View file

@ -100,27 +100,20 @@ The following commands configure the tray.
The _button_ argument in all cases is a platform-specific button code. On Linux The _button_ argument in all cases is a platform-specific button code. On Linux
you can find a list of these at linux/input-event-codes.h. you can find a list of these at linux/input-event-codes.h.
*activate\_button* <button> *tray\_bindsym* button<n> ContextMenu|Activate|SecondaryActivate|ScrollDown|ScrollLeft|ScrollRight|ScrollUp|nop
Sets the button to be used for the _activate_ (primary click) tray item Binds mouse button _n_ (1 to 9) to the specified action. Use the command
event. The default is BTN\_LEFT (0x110). _nop_ to disable the default action (Activate for button 1, ContextMenu for
button 2 and SecondaryActivate for button 3).
*context\_button* <button>
Sets the button to be used for the _context menu_ (right click) tray item
event. The default is BTN\_RIGHT (0x111).
*secondary\_button* <button>
Sets the button to be used for the _secondary_ (middle click) tray item
event. The default is BTN\_MIDDLE (0x112).
*tray\_output* none|all|<output>
Sets the output that the tray will appear on or none. Unlike i3bar, swaybar
is able to show icons on any number of bars and outputs without races.
The default is _all_.
*tray\_padding* <px> [px] *tray\_padding* <px> [px]
Sets the pixel padding of the system tray. This padding will surround the Sets the pixel padding of the system tray. This padding will surround the
tray on all sides and between each item. The default value for _px_ is 2. tray on all sides and between each item. The default value for _px_ is 2.
*tray\_output* none|<output>
Restrict the tray to a certain output, can be specified multiple times. If
omitted, the tray will be displayed on all outputs. Unlike i3bar, swaybar
can show icons on any number of bars and outputs without races.
*icon\_theme* <name> *icon\_theme* <name>
Sets the icon theme that sway will look for item icons in. This option has Sets the icon theme that sway will look for item icons in. This option has
no default value, because sway will always default to the fallback theme, no default value, because sway will always default to the fallback theme,

View file

@ -11,6 +11,7 @@
#include <wayland-client.h> #include <wayland-client.h>
#include <wayland-cursor.h> #include <wayland-cursor.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "config.h"
#include "swaybar/bar.h" #include "swaybar/bar.h"
#include "swaybar/config.h" #include "swaybar/config.h"
#include "swaybar/i3bar.h" #include "swaybar/i3bar.h"

View file

@ -4,6 +4,7 @@
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "swaybar/config.h" #include "swaybar/config.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h"
#include "config.h"
#include "stringop.h" #include "stringop.h"
#include "list.h" #include "list.h"
@ -73,6 +74,10 @@ struct swaybar_config *init_config(void) {
config->colors.binding_mode.background = 0x900000FF; config->colors.binding_mode.background = 0x900000FF;
config->colors.binding_mode.text = 0xFFFFFFFF; config->colors.binding_mode.text = 0xFFFFFFFF;
#if HAVE_TRAY
config->tray_padding = 2;
#endif
return config; return config;
} }
@ -102,5 +107,12 @@ void free_config(struct swaybar_config *config) {
free(coutput->name); free(coutput->name);
free(coutput); free(coutput);
} }
#if HAVE_TRAY
list_free_items_and_destroy(config->tray_outputs);
for (int i = 0; i < 10; ++i) {
free(config->tray_bindings[i]);
}
free(config->icon_theme);
#endif
free(config); free(config);
} }

View file

@ -6,6 +6,7 @@
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "swaybar/config.h" #include "swaybar/config.h"
#include "swaybar/ipc.h" #include "swaybar/ipc.h"
#include "config.h"
#include "ipc-client.h" #include "ipc-client.h"
#include "list.h" #include "list.h"
@ -282,6 +283,39 @@ static bool ipc_parse_config(
ipc_parse_colors(config, colors); ipc_parse_colors(config, colors);
} }
#if HAVE_TRAY
json_object *tray_outputs, *tray_padding, *tray_bindings, *icon_theme;
if ((json_object_object_get_ex(bar_config, "tray_outputs", &tray_outputs))) {
config->tray_outputs = create_list();
int length = json_object_array_length(tray_outputs);
for (int i = 0; i < length; ++i) {
json_object *o = json_object_array_get_idx(tray_outputs, i);
list_add(config->tray_outputs, strdup(json_object_get_string(o)));
}
}
if ((json_object_object_get_ex(bar_config, "tray_padding", &tray_padding))) {
config->tray_padding = json_object_get_int(tray_padding);
}
if ((json_object_object_get_ex(bar_config, "tray_bindings", &tray_bindings))) {
int length = json_object_array_length(tray_bindings);
for (int i = 0; i < length; ++i) {
json_object *bind = json_object_array_get_idx(tray_bindings, i);
json_object *button, *command;
json_object_object_get_ex(bind, "input_code", &button);
json_object_object_get_ex(bind, "command", &command);
config->tray_bindings[json_object_get_int(button)] =
strdup(json_object_get_string(command));
}
}
if ((json_object_object_get_ex(bar_config, "icon_theme", &icon_theme))) {
config->icon_theme = strdup(json_object_get_string(icon_theme));
}
#endif
json_object_put(bar_config); json_object_put(bar_config);
return true; return true;
} }