mirror of
https://github.com/swaywm/sway.git
synced 2024-11-04 15:33:13 +00:00
swaybar: complete barconfig_update event handling
This adds complete support for the barconfig_update ipc event. This also changes the bar command and subcommand handlers to correctly emit the event. This makes it so all bar subcommands other than id and swaybar_command are dynamically changeable at runtime. sway-bar.5 has been updated accordingly
This commit is contained in:
parent
187306640b
commit
1fd2c6ba49
|
@ -41,6 +41,7 @@ struct swaybar {
|
||||||
int ipc_socketfd;
|
int ipc_socketfd;
|
||||||
|
|
||||||
struct wl_list outputs; // swaybar_output::link
|
struct wl_list outputs; // swaybar_output::link
|
||||||
|
struct wl_list unused_outputs; // swaybar_output::link
|
||||||
struct wl_list seats; // swaybar_seat::link
|
struct wl_list seats; // swaybar_seat::link
|
||||||
|
|
||||||
#if HAVE_TRAY
|
#if HAVE_TRAY
|
||||||
|
@ -109,4 +110,8 @@ void set_bar_dirty(struct swaybar *bar);
|
||||||
bool determine_bar_visibility(struct swaybar *bar, bool moving_layer);
|
bool determine_bar_visibility(struct swaybar *bar, bool moving_layer);
|
||||||
void free_workspaces(struct wl_list *list);
|
void free_workspaces(struct wl_list *list);
|
||||||
|
|
||||||
|
void status_in(int fd, short mask, void *data);
|
||||||
|
|
||||||
|
void destroy_layer_surface(struct swaybar_output *output);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,7 +16,6 @@ struct box_colors {
|
||||||
struct config_output {
|
struct config_output {
|
||||||
struct wl_list link; // swaybar_config::outputs
|
struct wl_list link; // swaybar_config::outputs
|
||||||
char *name;
|
char *name;
|
||||||
size_t index;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct swaybar_binding {
|
struct swaybar_binding {
|
||||||
|
@ -41,7 +40,6 @@ struct swaybar_config {
|
||||||
bool workspace_buttons;
|
bool workspace_buttons;
|
||||||
list_t *bindings;
|
list_t *bindings;
|
||||||
struct wl_list outputs; // config_output::link
|
struct wl_list outputs; // config_output::link
|
||||||
bool all_outputs;
|
|
||||||
int height;
|
int height;
|
||||||
int status_padding;
|
int status_padding;
|
||||||
int status_edge_padding;
|
int status_edge_padding;
|
||||||
|
@ -83,10 +81,13 @@ struct tray_binding {
|
||||||
char *command;
|
char *command;
|
||||||
struct wl_list link; // struct tray_binding::link
|
struct wl_list link; // struct tray_binding::link
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void free_tray_binding(struct tray_binding *binding);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct swaybar_config *init_config(void);
|
struct swaybar_config *init_config(void);
|
||||||
void free_config(struct swaybar_config *config);
|
void free_config(struct swaybar_config *config);
|
||||||
uint32_t parse_position(const char *position);
|
uint32_t parse_position(const char *position);
|
||||||
|
void free_binding(struct swaybar_binding *binding);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
#include "sway/ipc-server.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
// Must be in alphabetical order for bsearch
|
// Must be in alphabetical order for bsearch
|
||||||
|
@ -56,30 +57,27 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool spawn = false;
|
char *id = NULL;
|
||||||
struct bar_config *bar = NULL;
|
|
||||||
if (strcmp(argv[0], "id") != 0 && is_subcommand(argv[1])) {
|
if (strcmp(argv[0], "id") != 0 && is_subcommand(argv[1])) {
|
||||||
for (int i = 0; i < config->bars->length; ++i) {
|
for (int i = 0; i < config->bars->length; ++i) {
|
||||||
struct bar_config *item = config->bars->items[i];
|
struct bar_config *item = config->bars->items[i];
|
||||||
if (strcmp(item->id, argv[0]) == 0) {
|
if (strcmp(item->id, argv[0]) == 0) {
|
||||||
sway_log(SWAY_DEBUG, "Selecting bar: %s", argv[0]);
|
sway_log(SWAY_DEBUG, "Selecting bar: %s", argv[0]);
|
||||||
bar = item;
|
config->current_bar = item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bar) {
|
if (!config->current_bar) {
|
||||||
spawn = !config->reading;
|
id = strdup(argv[0]);
|
||||||
sway_log(SWAY_DEBUG, "Creating bar: %s", argv[0]);
|
|
||||||
bar = default_bar_config();
|
|
||||||
if (!bar) {
|
|
||||||
return cmd_results_new(CMD_FAILURE,
|
|
||||||
"Unable to allocate bar state");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bar->id = strdup(argv[0]);
|
|
||||||
}
|
|
||||||
config->current_bar = bar;
|
|
||||||
++argv; --argc;
|
++argv; --argc;
|
||||||
|
} else if (config->reading && !config->current_bar) {
|
||||||
|
int len = snprintf(NULL, 0, "bar-%d", config->bars->length) + 1;
|
||||||
|
id = malloc(len * sizeof(char));
|
||||||
|
if (!id) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "Unable to allocate bar id");
|
||||||
|
}
|
||||||
|
snprintf(id, len, "bar-%d", config->bars->length);
|
||||||
} else if (!config->reading && strcmp(argv[0], "mode") != 0 &&
|
} else if (!config->reading && strcmp(argv[0], "mode") != 0 &&
|
||||||
strcmp(argv[0], "hidden_state") != 0) {
|
strcmp(argv[0], "hidden_state") != 0) {
|
||||||
if (is_subcommand(argv[0])) {
|
if (is_subcommand(argv[0])) {
|
||||||
|
@ -90,56 +88,49 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
sway_log(SWAY_DEBUG, "Creating bar: %s", id);
|
||||||
|
config->current_bar = default_bar_config();
|
||||||
if (!config->current_bar) {
|
if (!config->current_bar) {
|
||||||
if (config->reading) {
|
free(id);
|
||||||
// Create new bar with default values
|
return cmd_results_new(CMD_FAILURE, "Unable to allocate bar config");
|
||||||
struct bar_config *bar = default_bar_config();
|
}
|
||||||
if (!bar) {
|
config->current_bar->id = id;
|
||||||
return cmd_results_new(CMD_FAILURE,
|
|
||||||
"Unable to allocate bar state");
|
|
||||||
}
|
|
||||||
|
|
||||||
// set bar id
|
|
||||||
int len = snprintf(NULL, 0, "bar-%d", config->bars->length - 1) + 1;
|
|
||||||
bar->id = malloc(len * sizeof(char));
|
|
||||||
if (bar->id) {
|
|
||||||
snprintf(bar->id, len, "bar-%d", config->bars->length - 1);
|
|
||||||
} else {
|
|
||||||
return cmd_results_new(CMD_FAILURE, "Unable to allocate bar ID");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set current bar
|
|
||||||
config->current_bar = bar;
|
|
||||||
sway_log(SWAY_DEBUG, "Creating bar %s", bar->id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cmd_results *res = NULL;
|
||||||
if (find_handler(argv[0], bar_config_handlers,
|
if (find_handler(argv[0], bar_config_handlers,
|
||||||
sizeof(bar_config_handlers))) {
|
sizeof(bar_config_handlers))) {
|
||||||
if (config->reading) {
|
if (config->reading) {
|
||||||
return config_subcommand(argv, argc, bar_config_handlers,
|
res = config_subcommand(argv, argc, bar_config_handlers,
|
||||||
sizeof(bar_config_handlers));
|
sizeof(bar_config_handlers));
|
||||||
} else if (spawn) {
|
} else {
|
||||||
for (int i = config->bars->length - 1; i >= 0; i--) {
|
res = cmd_results_new(CMD_INVALID,
|
||||||
struct bar_config *bar = config->bars->items[i];
|
"Can only be used in the config file");
|
||||||
if (bar == config->current_bar) {
|
|
||||||
list_del(config->bars, i);
|
|
||||||
free_bar_config(bar);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
res = config_subcommand(argv, argc, bar_handlers, sizeof(bar_handlers));
|
||||||
return cmd_results_new(CMD_INVALID,
|
|
||||||
"Can only be used in the config file.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmd_results *res =
|
if (res && res->status != CMD_SUCCESS) {
|
||||||
config_subcommand(argv, argc, bar_handlers, sizeof(bar_handlers));
|
if (id) {
|
||||||
if (!config->reading) {
|
free_bar_config(config->current_bar);
|
||||||
if (spawn) {
|
id = NULL;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
list_add(config->bars, config->current_bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config->reading && config->current_bar) {
|
||||||
|
ipc_event_barconfig_update(config->current_bar);
|
||||||
|
if (id) {
|
||||||
load_swaybar(config->current_bar);
|
load_swaybar(config->current_bar);
|
||||||
}
|
}
|
||||||
config->current_bar = NULL;
|
config->current_bar = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ static struct cmd_results *bar_set_hidden_state(struct bar_config *bar,
|
||||||
return cmd_results_new(CMD_INVALID, "Invalid value %s", hidden_state);
|
return cmd_results_new(CMD_INVALID, "Invalid value %s", hidden_state);
|
||||||
}
|
}
|
||||||
if (strcmp(old_state, bar->hidden_state) != 0) {
|
if (strcmp(old_state, bar->hidden_state) != 0) {
|
||||||
if (!config->reading) {
|
if (!config->current_bar) {
|
||||||
ipc_event_barconfig_update(bar);
|
ipc_event_barconfig_update(bar);
|
||||||
}
|
}
|
||||||
sway_log(SWAY_DEBUG, "Setting hidden_state: '%s' for bar: %s",
|
sway_log(SWAY_DEBUG, "Setting hidden_state: '%s' for bar: %s",
|
||||||
|
@ -47,6 +47,12 @@ struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) {
|
||||||
"Unexpected value %s in config mode", argv[1]);
|
"Unexpected value %s in config mode", argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config->current_bar && argc == 2 &&
|
||||||
|
strcmp(config->current_bar->id, argv[1]) != 0) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "Conflicting bar ids: %s and %s",
|
||||||
|
config->current_bar->id, argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
const char *state = argv[0];
|
const char *state = argv[0];
|
||||||
if (config->reading) {
|
if (config->reading) {
|
||||||
error = bar_set_hidden_state(config->current_bar, state);
|
error = bar_set_hidden_state(config->current_bar, state);
|
||||||
|
|
|
@ -27,7 +27,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(old_mode, bar->mode) != 0) {
|
if (strcmp(old_mode, bar->mode) != 0) {
|
||||||
if (!config->reading) {
|
if (!config->current_bar) {
|
||||||
ipc_event_barconfig_update(bar);
|
ipc_event_barconfig_update(bar);
|
||||||
}
|
}
|
||||||
sway_log(SWAY_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
|
sway_log(SWAY_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
|
||||||
|
@ -51,6 +51,12 @@ struct cmd_results *bar_cmd_mode(int argc, char **argv) {
|
||||||
"Unexpected value %s in config mode", argv[1]);
|
"Unexpected value %s in config mode", argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config->current_bar && argc == 2 &&
|
||||||
|
strcmp(config->current_bar->id, argv[1]) != 0) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "Conflicting bar ids: %s and %s",
|
||||||
|
config->current_bar->id, argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
const char *mode = argv[0];
|
const char *mode = argv[0];
|
||||||
if (config->reading) {
|
if (config->reading) {
|
||||||
error = bar_set_mode(config->current_bar, mode);
|
error = bar_set_mode(config->current_bar, mode);
|
||||||
|
|
|
@ -21,16 +21,19 @@ struct cmd_results *bar_cmd_output(int argc, char **argv) {
|
||||||
bool add_output = true;
|
bool add_output = true;
|
||||||
if (strcmp("*", output) == 0) {
|
if (strcmp("*", output) == 0) {
|
||||||
// remove all previous defined outputs and replace with '*'
|
// remove all previous defined outputs and replace with '*'
|
||||||
for (int i = 0; i < outputs->length; ++i) {
|
while (outputs->length) {
|
||||||
free(outputs->items[i]);
|
free(outputs->items[0]);
|
||||||
list_del(outputs, i);
|
list_del(outputs, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// only add output if not already defined with either the same
|
// only add output if not already defined, if the list has '*', remove
|
||||||
// name or as '*'
|
// it, in favor of a manual list
|
||||||
for (int i = 0; i < outputs->length; ++i) {
|
for (int i = 0; i < outputs->length; ++i) {
|
||||||
const char *find = outputs->items[i];
|
const char *find = outputs->items[i];
|
||||||
if (strcmp("*", find) == 0 || strcmp(output, find) == 0) {
|
if (strcmp("*", find) == 0) {
|
||||||
|
free(outputs->items[i]);
|
||||||
|
list_del(outputs, i);
|
||||||
|
} else if (strcmp(output, find) == 0) {
|
||||||
add_output = false;
|
add_output = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,5 @@ struct cmd_results *bar_cmd_status_command(int argc, char **argv) {
|
||||||
} else {
|
} else {
|
||||||
free(new_command);
|
free(new_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->active && !config->validating) {
|
|
||||||
load_swaybar(config->current_bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,21 @@ struct cmd_results *bar_cmd_tray_output(int argc, char **argv) {
|
||||||
free(outputs->items[i]);
|
free(outputs->items[i]);
|
||||||
}
|
}
|
||||||
outputs->length = 0;
|
outputs->length = 0;
|
||||||
|
} else if (strcmp(argv[0], "*") == 0) {
|
||||||
|
sway_log(SWAY_DEBUG, "Showing tray on all outputs for bar: %s",
|
||||||
|
config->current_bar->id);
|
||||||
|
while (outputs->length) {
|
||||||
|
free(outputs->items[0]);
|
||||||
|
list_del(outputs, 0);
|
||||||
|
}
|
||||||
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
} else {
|
} else {
|
||||||
sway_log(SWAY_DEBUG, "Showing tray on output '%s' for bar: %s", argv[0],
|
sway_log(SWAY_DEBUG, "Showing tray on output '%s' for bar: %s", argv[0],
|
||||||
config->current_bar->id);
|
config->current_bar->id);
|
||||||
|
if (outputs->length == 1 && strcmp(outputs->items[0], "none") == 0) {
|
||||||
|
free(outputs->items[0]);
|
||||||
|
list_del(outputs, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
list_add(outputs, strdup(argv[0]));
|
list_add(outputs, strdup(argv[0]));
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,6 @@ struct bar_config *default_bar_config(void) {
|
||||||
wl_list_init(&bar->tray_bindings);
|
wl_list_init(&bar->tray_bindings);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_add(config->bars, bar);
|
|
||||||
return bar;
|
return bar;
|
||||||
cleanup:
|
cleanup:
|
||||||
free_bar_config(bar);
|
free_bar_config(bar);
|
||||||
|
|
|
@ -10,67 +10,16 @@ Sway allows configuring swaybar in the sway configuration file.
|
||||||
|
|
||||||
# COMMANDS
|
# COMMANDS
|
||||||
|
|
||||||
*status_command* <status command>
|
The following commands may only be used in the configuration file.
|
||||||
Executes the bar _status command_ with _sh -c_. Each line of text printed
|
|
||||||
to stdout from this command will be displayed in the status area of the
|
|
||||||
bar. You may also use swaybar's JSON status line protocol. See
|
|
||||||
*swaybar-protocol*(7) for more information on the protocol
|
|
||||||
|
|
||||||
If running this command via IPC, you can disable a running status command by
|
|
||||||
setting the command to a single dash: _swaybar bar bar-0 status\_command -_
|
|
||||||
|
|
||||||
*pango_markup* enabled|disabled
|
|
||||||
Enables or disables pango markup for status lines. This has no effect on
|
|
||||||
status lines using the i3bar JSON protocol.
|
|
||||||
|
|
||||||
*id* <bar_id>
|
*id* <bar_id>
|
||||||
Sets the ID of the bar.
|
Sets the ID of the bar.
|
||||||
|
|
||||||
*position* top|bottom
|
|
||||||
Sets position of the bar. Default is _bottom_.
|
|
||||||
|
|
||||||
*output* <output>
|
|
||||||
Restrict the bar to a certain output, can be specified multiple times. If
|
|
||||||
the output command is omitted, the bar will be displayed on all outputs.
|
|
||||||
|
|
||||||
*swaybar_command* <command>
|
*swaybar_command* <command>
|
||||||
Executes custom bar command. Default is _swaybar_.
|
Executes custom bar command. Default is _swaybar_.
|
||||||
|
|
||||||
*font* <font>
|
The following commands may be used either in the configuration file or at
|
||||||
Specifies the font to be used in the bar. _font_ should be specified as a
|
runtime.
|
||||||
pango font description. For more information on pango font descriptions,
|
|
||||||
see https://developer.gnome.org/pango/stable/pango-Fonts.html#pango-font-description-from-string
|
|
||||||
|
|
||||||
*separator_symbol* <symbol>
|
|
||||||
Specifies the separator symbol to separate blocks on the bar.
|
|
||||||
|
|
||||||
*wrap_scroll* yes|no
|
|
||||||
Enables or disables wrapping when scrolling through workspaces with the
|
|
||||||
scroll wheel. Default is _no_.
|
|
||||||
|
|
||||||
*workspace_buttons* yes|no
|
|
||||||
Enables or disables workspace buttons on the bar. Default is _yes_.
|
|
||||||
|
|
||||||
*strip_workspace_name* yes|no
|
|
||||||
If set to _yes_, then workspace names will be omitted from the workspace
|
|
||||||
button and only the custom number will be shown. Default is _no_.
|
|
||||||
|
|
||||||
*strip_workspace_numbers* yes|no
|
|
||||||
If set to _yes_, then workspace numbers will be omitted from the workspace
|
|
||||||
button and only the custom name will be shown. Default is _no_.
|
|
||||||
|
|
||||||
*binding_mode_indicator* yes|no
|
|
||||||
Enable or disable binding mode indicator. Default is _yes_.
|
|
||||||
|
|
||||||
*gaps* <all> | <horizontal> <vertical> | <top> <right> <bottom> <left>
|
|
||||||
Sets the gaps from the edge of the screen for the bar. Gaps can either be
|
|
||||||
set all at once, per direction, or per side. Note that only sides that
|
|
||||||
touch an edge of the screen can have gaps. For the side that does not
|
|
||||||
touch an edge of the screen, per-side outer gaps for workspaces may be of
|
|
||||||
use.
|
|
||||||
|
|
||||||
*height* <height>
|
|
||||||
Sets the height of the bar. Default height (0) will match the font size.
|
|
||||||
|
|
||||||
*bindcode* [--release] <event-code> <command>
|
*bindcode* [--release] <event-code> <command>
|
||||||
Executes _command_ when the mouse button has been pressed (or if _released_
|
Executes _command_ when the mouse button has been pressed (or if _released_
|
||||||
|
@ -85,7 +34,39 @@ Sway allows configuring swaybar in the sway configuration file.
|
||||||
debug-events*. To disable the default behavior for a button, use the
|
debug-events*. To disable the default behavior for a button, use the
|
||||||
command _nop_.
|
command _nop_.
|
||||||
|
|
||||||
*mode* dock|hide|invisible|overlay
|
*binding_mode_indicator* yes|no
|
||||||
|
Enable or disable binding mode indicator. Default is _yes_.
|
||||||
|
|
||||||
|
*font* <font>
|
||||||
|
Specifies the font to be used in the bar. _font_ should be specified as a
|
||||||
|
pango font description. For more information on pango font descriptions,
|
||||||
|
see https://developer.gnome.org/pango/stable/pango-Fonts.html#pango-font-description-from-string
|
||||||
|
|
||||||
|
*gaps* <all> | <horizontal> <vertical> | <top> <right> <bottom> <left>
|
||||||
|
Sets the gaps from the edge of the screen for the bar. Gaps can either be
|
||||||
|
set all at once, per direction, or per side. Note that only sides that
|
||||||
|
touch an edge of the screen can have gaps. For the side that does not
|
||||||
|
touch an edge of the screen, per-side outer gaps for workspaces may be of
|
||||||
|
use.
|
||||||
|
|
||||||
|
*height* <height>
|
||||||
|
Sets the height of the bar. Default height (0) will match the font size.
|
||||||
|
|
||||||
|
*hidden_state* hide|show [<bar-id>]
|
||||||
|
Specifies the behaviour of the bar when it is in _hide_ mode. When the
|
||||||
|
hidden state is _hide_, then it is normally hidden, and only unhidden by
|
||||||
|
pressing the modifier key or in case of urgency hints. When the hidden
|
||||||
|
state is _show_, then it is permanently visible, drawn on top of the
|
||||||
|
currently visible workspace. Default is _hide_.
|
||||||
|
|
||||||
|
For compatibility with i3, _bar hidden_state hide|show [<bar-id>]_ is
|
||||||
|
supported along with the sway only _bar <bar-id> hidden_state hide|show_
|
||||||
|
syntax. When using the i3 syntax, if _bar-id_ is omitted, the hidden_state
|
||||||
|
will be changed for all bars. Attempting to use _bar <bar-id1>
|
||||||
|
hidden_state hide|show <bar-id2>_ will result in an error due to
|
||||||
|
conflicting bar ids.
|
||||||
|
|
||||||
|
*mode* dock|hide|invisible|overlay [<bar-id>]
|
||||||
Specifies the visibility of the bar. In _dock_ mode, it is permanently
|
Specifies the visibility of the bar. In _dock_ mode, it is permanently
|
||||||
visible at one edge of the screen. In _hide_ mode, it is hidden unless the
|
visible at one edge of the screen. In _hide_ mode, it is hidden unless the
|
||||||
modifier key is pressed, though this behaviour depends on the hidden state.
|
modifier key is pressed, though this behaviour depends on the hidden state.
|
||||||
|
@ -93,32 +74,70 @@ Sway allows configuring swaybar in the sway configuration file.
|
||||||
permanently visible on top of other windows. (In _overlay_ mode the bar is
|
permanently visible on top of other windows. (In _overlay_ mode the bar is
|
||||||
transparent to input events.) Default is _dock_.
|
transparent to input events.) Default is _dock_.
|
||||||
|
|
||||||
*hidden_state* hide|show
|
For compatibility with i3, _bar mode <mode> [<bar-id>]_ syntax is supported
|
||||||
Specifies the behaviour of the bar when it is in _hide_ mode. When the
|
along with the sway only _bar <bar-id> mode <mode>_ syntax. When using the
|
||||||
hidden state is _hide_, then it is normally hidden, and only unhidden by
|
i3 syntax, if _bar-id_ is omitted, the mode will be changed for all bars.
|
||||||
pressing the modifier key or in case of urgency hints. When the hidden
|
Attempting to use _bar <bar-id1> mode <mode> <bar-id2>_ will result in an
|
||||||
state is _show_, then it is permanently visible, drawn on top of the
|
error due to conflicting bar ids.
|
||||||
currently visible workspace. Default is _hide_.
|
|
||||||
|
|
||||||
*modifier* <Modifier>|none
|
*modifier* <Modifier>|none
|
||||||
Specifies the modifier key that shows a hidden bar. Default is _Mod4_.
|
Specifies the modifier key that shows a hidden bar. Default is _Mod4_.
|
||||||
|
|
||||||
*status_padding* <padding>
|
*output* <output>|\*
|
||||||
Sets the vertical padding that is used for the status line. The default is
|
Restrict the bar to a certain output, can be specified multiple times. If
|
||||||
_1_. If _padding_ is _0_, blocks will be able to take up the full height of
|
the output command is omitted, the bar will be displayed on all outputs. _\*_
|
||||||
the bar. This value will be multiplied by the output scale.
|
can be given at any point to reset it back to all outputs.
|
||||||
|
|
||||||
|
*pango_markup* enabled|disabled
|
||||||
|
Enables or disables pango markup for status lines. This has no effect on
|
||||||
|
status lines using the i3bar JSON protocol.
|
||||||
|
|
||||||
|
*position* top|bottom
|
||||||
|
Sets position of the bar. Default is _bottom_.
|
||||||
|
|
||||||
|
*separator_symbol* <symbol>
|
||||||
|
Specifies the separator symbol to separate blocks on the bar.
|
||||||
|
|
||||||
|
*status_command* <status command>
|
||||||
|
Executes the bar _status command_ with _sh -c_. Each line of text printed
|
||||||
|
to stdout from this command will be displayed in the status area of the
|
||||||
|
bar. You may also use swaybar's JSON status line protocol. See
|
||||||
|
*swaybar-protocol*(7) for more information on the protocol
|
||||||
|
|
||||||
|
If running this command via IPC, you can disable a running status command by
|
||||||
|
setting the command to a single dash: _swaybar bar bar-0 status\_command -_
|
||||||
|
|
||||||
*status_edge_padding* <padding>
|
*status_edge_padding* <padding>
|
||||||
Sets the padding that is used when the status line is at the right edge of
|
Sets the padding that is used when the status line is at the right edge of
|
||||||
the bar. This value will be multiplied by the output scale. The default is
|
the bar. This value will be multiplied by the output scale. The default is
|
||||||
_3_.
|
_3_.
|
||||||
|
|
||||||
|
*status_padding* <padding>
|
||||||
|
Sets the vertical padding that is used for the status line. The default is
|
||||||
|
_1_. If _padding_ is _0_, blocks will be able to take up the full height of
|
||||||
|
the bar. This value will be multiplied by the output scale.
|
||||||
|
|
||||||
|
*strip_workspace_name* yes|no
|
||||||
|
If set to _yes_, then workspace names will be omitted from the workspace
|
||||||
|
button and only the custom number will be shown. Default is _no_.
|
||||||
|
|
||||||
|
*strip_workspace_numbers* yes|no
|
||||||
|
If set to _yes_, then workspace numbers will be omitted from the workspace
|
||||||
|
button and only the custom name will be shown. Default is _no_.
|
||||||
|
|
||||||
*unbindcode* [--release] <event-code>
|
*unbindcode* [--release] <event-code>
|
||||||
Removes the binding with the given <event-code>.
|
Removes the binding with the given <event-code>.
|
||||||
|
|
||||||
*unbindsym* [--release] button[1-9]|<event-name>
|
*unbindsym* [--release] button[1-9]|<event-name>
|
||||||
Removes the binding with the given <button> or <event-name>.
|
Removes the binding with the given <button> or <event-name>.
|
||||||
|
|
||||||
|
*wrap_scroll* yes|no
|
||||||
|
Enables or disables wrapping when scrolling through workspaces with the
|
||||||
|
scroll wheel. Default is _no_.
|
||||||
|
|
||||||
|
*workspace_buttons* yes|no
|
||||||
|
Enables or disables workspace buttons on the bar. Default is _yes_.
|
||||||
|
|
||||||
## TRAY
|
## TRAY
|
||||||
|
|
||||||
Swaybar provides a system tray where third-party applications may place icons.
|
Swaybar provides a system tray where third-party applications may place icons.
|
||||||
|
@ -142,10 +161,11 @@ ContextMenu|Activate|SecondaryActivate|ScrollDown|ScrollLeft|ScrollRight|ScrollU
|
||||||
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>
|
*tray_output* none|<output>|\*
|
||||||
Restrict the tray to a certain output, can be specified multiple times. If
|
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
|
omitted, the tray will be displayed on all outputs. Unlike i3bar, swaybar
|
||||||
can show icons on any number of bars and outputs without races.
|
can show icons on any number of bars and outputs without races. _\*_ can be
|
||||||
|
given at any point to reset it to display on all outputs.
|
||||||
|
|
||||||
*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
|
||||||
|
|
|
@ -755,18 +755,6 @@ The default colors are:
|
||||||
*workspace_layout* default|stacking|tabbed
|
*workspace_layout* default|stacking|tabbed
|
||||||
Specifies the initial layout for new workspaces.
|
Specifies the initial layout for new workspaces.
|
||||||
|
|
||||||
# BAR CONTROL
|
|
||||||
|
|
||||||
*bar hidden_state* hide|show|toggle [<bar_id>]
|
|
||||||
Sets the hidden state of the bar (see *sway-bar*(5)), either individually,
|
|
||||||
by specifying a bar id, or if none is given, for all bar instances.
|
|
||||||
_toggle_ switches between _hide_ and _show_.
|
|
||||||
|
|
||||||
*bar mode* dock|hide|invisible|toggle [<bar_id>]
|
|
||||||
Sets the mode of the bar (see *sway-bar*(5)), either individually,
|
|
||||||
by specifying a bar id, or if none is given, for all bar instances.
|
|
||||||
_toggle_ switches between _dock_ and _hide_.
|
|
||||||
|
|
||||||
# CRITERIA
|
# CRITERIA
|
||||||
|
|
||||||
A criteria is a string in the form of, for example:
|
A criteria is a string in the form of, for example:
|
||||||
|
|
|
@ -126,7 +126,7 @@ static void add_layer_surface(struct swaybar_output *output) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_layer_surface(struct swaybar_output *output) {
|
void destroy_layer_surface(struct swaybar_output *output) {
|
||||||
if (!output->layer_surface) {
|
if (!output->layer_surface) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ bool determine_bar_visibility(struct swaybar *bar, bool moving_layer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bar_uses_output(struct swaybar_output *output) {
|
static bool bar_uses_output(struct swaybar_output *output) {
|
||||||
if (output->bar->config->all_outputs) {
|
if (wl_list_empty(&output->bar->config->outputs)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
char *identifier = output->identifier;
|
char *identifier = output->identifier;
|
||||||
|
@ -256,13 +256,17 @@ static void xdg_output_handle_done(void *data,
|
||||||
struct swaybar_output *output = data;
|
struct swaybar_output *output = data;
|
||||||
struct swaybar *bar = output->bar;
|
struct swaybar *bar = output->bar;
|
||||||
|
|
||||||
assert(output->name != NULL);
|
if (!wl_list_empty(&output->link)) {
|
||||||
if (!bar_uses_output(output)) {
|
return;
|
||||||
swaybar_output_free(output);
|
}
|
||||||
|
|
||||||
|
assert(output->name != NULL);
|
||||||
|
if (!bar_uses_output(output)) {
|
||||||
|
wl_list_remove(&output->link);
|
||||||
|
wl_list_insert(&bar->unused_outputs, &output->link);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wl_list_empty(&output->link)) {
|
|
||||||
wl_list_remove(&output->link);
|
wl_list_remove(&output->link);
|
||||||
wl_list_insert(&bar->outputs, &output->link);
|
wl_list_insert(&bar->outputs, &output->link);
|
||||||
|
|
||||||
|
@ -270,6 +274,9 @@ static void xdg_output_handle_done(void *data,
|
||||||
assert(output->surface);
|
assert(output->surface);
|
||||||
|
|
||||||
determine_bar_visibility(bar, false);
|
determine_bar_visibility(bar, false);
|
||||||
|
|
||||||
|
if (bar->running && bar->config->workspace_buttons) {
|
||||||
|
ipc_get_workspaces(bar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,6 +380,12 @@ static void handle_global_remove(void *data, struct wl_registry *registry,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wl_list_for_each_safe(output, tmp, &bar->unused_outputs, link) {
|
||||||
|
if (output->wl_name == name) {
|
||||||
|
swaybar_output_free(output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
struct swaybar_seat *seat, *tmp_seat;
|
struct swaybar_seat *seat, *tmp_seat;
|
||||||
wl_list_for_each_safe(seat, tmp_seat, &bar->seats, link) {
|
wl_list_for_each_safe(seat, tmp_seat, &bar->seats, link) {
|
||||||
if (seat->wl_name == name) {
|
if (seat->wl_name == name) {
|
||||||
|
@ -391,6 +404,7 @@ bool bar_setup(struct swaybar *bar, const char *socket_path) {
|
||||||
bar->visible = true;
|
bar->visible = true;
|
||||||
bar->config = init_config();
|
bar->config = init_config();
|
||||||
wl_list_init(&bar->outputs);
|
wl_list_init(&bar->outputs);
|
||||||
|
wl_list_init(&bar->unused_outputs);
|
||||||
wl_list_init(&bar->seats);
|
wl_list_init(&bar->seats);
|
||||||
bar->eventloop = loop_create();
|
bar->eventloop = loop_create();
|
||||||
|
|
||||||
|
@ -458,7 +472,7 @@ static void ipc_in(int fd, short mask, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void status_in(int fd, short mask, void *data) {
|
void status_in(int fd, short mask, void *data) {
|
||||||
struct swaybar *bar = data;
|
struct swaybar *bar = data;
|
||||||
if (mask & (POLLHUP | POLLERR)) {
|
if (mask & (POLLHUP | POLLERR)) {
|
||||||
status_error(bar->status, "[error reading from status command]");
|
status_error(bar->status, "[error reading from status command]");
|
||||||
|
@ -510,6 +524,7 @@ void bar_teardown(struct swaybar *bar) {
|
||||||
destroy_tray(bar->tray);
|
destroy_tray(bar->tray);
|
||||||
#endif
|
#endif
|
||||||
free_outputs(&bar->outputs);
|
free_outputs(&bar->outputs);
|
||||||
|
free_outputs(&bar->unused_outputs);
|
||||||
free_seats(&bar->seats);
|
free_seats(&bar->seats);
|
||||||
if (bar->config) {
|
if (bar->config) {
|
||||||
free_config(bar->config);
|
free_config(bar->config);
|
||||||
|
|
|
@ -84,7 +84,7 @@ struct swaybar_config *init_config(void) {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_binding(struct swaybar_binding *binding) {
|
void free_binding(struct swaybar_binding *binding) {
|
||||||
if (!binding) {
|
if (!binding) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ static void free_binding(struct swaybar_binding *binding) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_TRAY
|
#if HAVE_TRAY
|
||||||
static void free_tray_binding(struct tray_binding *binding) {
|
void free_tray_binding(struct tray_binding *binding) {
|
||||||
if (!binding) {
|
if (!binding) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
367
swaybar/ipc.c
367
swaybar/ipc.c
|
@ -1,15 +1,21 @@
|
||||||
#define _POSIX_C_SOURCE 200809
|
#define _POSIX_C_SOURCE 200809
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <json.h>
|
#include <json.h>
|
||||||
#include "swaybar/config.h"
|
#include "swaybar/config.h"
|
||||||
#include "swaybar/ipc.h"
|
#include "swaybar/ipc.h"
|
||||||
|
#include "swaybar/status_line.h"
|
||||||
|
#if HAVE_TRAY
|
||||||
|
#include "swaybar/tray/tray.h"
|
||||||
|
#endif
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "ipc-client.h"
|
#include "ipc-client.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "loop.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
void ipc_send_workspace_command(struct swaybar *bar, const char *ws) {
|
void ipc_send_workspace_command(struct swaybar *bar, const char *ws) {
|
||||||
|
@ -169,75 +175,58 @@ static bool ipc_parse_config(
|
||||||
json_object *success;
|
json_object *success;
|
||||||
if (json_object_object_get_ex(bar_config, "success", &success)
|
if (json_object_object_get_ex(bar_config, "success", &success)
|
||||||
&& !json_object_get_boolean(success)) {
|
&& !json_object_get_boolean(success)) {
|
||||||
sway_log(SWAY_ERROR, "No bar with that ID. Use 'swaymsg -t get_bar_config to get the available bar configs.");
|
sway_log(SWAY_ERROR, "No bar with that ID. Use 'swaymsg -t "
|
||||||
|
"get_bar_config' to get the available bar configs.");
|
||||||
json_object_put(bar_config);
|
json_object_put(bar_config);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
json_object *markup, *mode, *hidden_state, *position, *status_command;
|
|
||||||
json_object *font, *gaps, *bar_height, *wrap_scroll, *workspace_buttons;
|
json_object *bar_height = json_object_object_get(bar_config, "bar_height");
|
||||||
json_object *strip_workspace_numbers, *strip_workspace_name;
|
if (bar_height) {
|
||||||
json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol;
|
config->height = json_object_get_int(bar_height);
|
||||||
json_object *outputs, *bindings, *status_padding, *status_edge_padding;
|
|
||||||
json_object_object_get_ex(bar_config, "mode", &mode);
|
|
||||||
json_object_object_get_ex(bar_config, "hidden_state", &hidden_state);
|
|
||||||
json_object_object_get_ex(bar_config, "position", &position);
|
|
||||||
json_object_object_get_ex(bar_config, "status_command", &status_command);
|
|
||||||
json_object_object_get_ex(bar_config, "font", &font);
|
|
||||||
json_object_object_get_ex(bar_config, "gaps", &gaps);
|
|
||||||
json_object_object_get_ex(bar_config, "bar_height", &bar_height);
|
|
||||||
json_object_object_get_ex(bar_config, "wrap_scroll", &wrap_scroll);
|
|
||||||
json_object_object_get_ex(bar_config, "workspace_buttons", &workspace_buttons);
|
|
||||||
json_object_object_get_ex(bar_config, "strip_workspace_numbers", &strip_workspace_numbers);
|
|
||||||
json_object_object_get_ex(bar_config, "strip_workspace_name", &strip_workspace_name);
|
|
||||||
json_object_object_get_ex(bar_config, "binding_mode_indicator", &binding_mode_indicator);
|
|
||||||
json_object_object_get_ex(bar_config, "verbose", &verbose);
|
|
||||||
json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol);
|
|
||||||
json_object_object_get_ex(bar_config, "colors", &colors);
|
|
||||||
json_object_object_get_ex(bar_config, "outputs", &outputs);
|
|
||||||
json_object_object_get_ex(bar_config, "pango_markup", &markup);
|
|
||||||
json_object_object_get_ex(bar_config, "bindings", &bindings);
|
|
||||||
json_object_object_get_ex(bar_config, "status_padding", &status_padding);
|
|
||||||
json_object_object_get_ex(bar_config, "status_edge_padding",
|
|
||||||
&status_edge_padding);
|
|
||||||
if (status_command) {
|
|
||||||
free(config->status_command);
|
|
||||||
config->status_command = strdup(json_object_get_string(status_command));
|
|
||||||
}
|
}
|
||||||
if (position) {
|
|
||||||
config->position = parse_position(json_object_get_string(position));
|
json_object *binding_mode_indicator =
|
||||||
|
json_object_object_get(bar_config, "binding_mode_indicator");
|
||||||
|
if (binding_mode_indicator) {
|
||||||
|
config->binding_mode_indicator =
|
||||||
|
json_object_get_boolean(binding_mode_indicator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_object *bindings = json_object_object_get(bar_config, "bindings");
|
||||||
|
while (config->bindings->length) {
|
||||||
|
struct swaybar_binding *binding = config->bindings->items[0];
|
||||||
|
list_del(config->bindings, 0);
|
||||||
|
free_binding(binding);
|
||||||
|
}
|
||||||
|
if (bindings) {
|
||||||
|
int length = json_object_array_length(bindings);
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
json_object *bindobj = json_object_array_get_idx(bindings, i);
|
||||||
|
struct swaybar_binding *binding =
|
||||||
|
calloc(1, sizeof(struct swaybar_binding));
|
||||||
|
binding->button = json_object_get_int(
|
||||||
|
json_object_object_get(bindobj, "event_code"));
|
||||||
|
binding->command = strdup(json_object_get_string(
|
||||||
|
json_object_object_get(bindobj, "command")));
|
||||||
|
binding->release = json_object_get_boolean(
|
||||||
|
json_object_object_get(bindobj, "release"));
|
||||||
|
list_add(config->bindings, binding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *colors = json_object_object_get(bar_config, "colors");
|
||||||
|
if (colors) {
|
||||||
|
ipc_parse_colors(config, colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *font = json_object_object_get(bar_config, "font");
|
||||||
if (font) {
|
if (font) {
|
||||||
free(config->font);
|
free(config->font);
|
||||||
config->font = parse_font(json_object_get_string(font));
|
config->font = parse_font(json_object_get_string(font));
|
||||||
}
|
}
|
||||||
if (sep_symbol) {
|
|
||||||
free(config->sep_symbol);
|
json_object *gaps = json_object_object_get(bar_config, "gaps");
|
||||||
config->sep_symbol = strdup(json_object_get_string(sep_symbol));
|
|
||||||
}
|
|
||||||
if (strip_workspace_numbers) {
|
|
||||||
config->strip_workspace_numbers = json_object_get_boolean(strip_workspace_numbers);
|
|
||||||
}
|
|
||||||
if (strip_workspace_name) {
|
|
||||||
config->strip_workspace_name = json_object_get_boolean(strip_workspace_name);
|
|
||||||
}
|
|
||||||
if (binding_mode_indicator) {
|
|
||||||
config->binding_mode_indicator = json_object_get_boolean(binding_mode_indicator);
|
|
||||||
}
|
|
||||||
if (wrap_scroll) {
|
|
||||||
config->wrap_scroll = json_object_get_boolean(wrap_scroll);
|
|
||||||
}
|
|
||||||
if (workspace_buttons) {
|
|
||||||
config->workspace_buttons = json_object_get_boolean(workspace_buttons);
|
|
||||||
}
|
|
||||||
if (bar_height) {
|
|
||||||
config->height = json_object_get_int(bar_height);
|
|
||||||
}
|
|
||||||
if (status_padding) {
|
|
||||||
config->status_padding = json_object_get_int(status_padding);
|
|
||||||
}
|
|
||||||
if (status_edge_padding) {
|
|
||||||
config->status_edge_padding = json_object_get_int(status_edge_padding);
|
|
||||||
}
|
|
||||||
if (gaps) {
|
if (gaps) {
|
||||||
json_object *top = json_object_object_get(gaps, "top");
|
json_object *top = json_object_object_get(gaps, "top");
|
||||||
if (top) {
|
if (top) {
|
||||||
|
@ -256,33 +245,21 @@ static bool ipc_parse_config(
|
||||||
config->gaps.left = json_object_get_int(left);
|
config->gaps.left = json_object_get_int(left);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (markup) {
|
|
||||||
config->pango_markup = json_object_get_boolean(markup);
|
json_object *hidden_state =
|
||||||
}
|
json_object_object_get(bar_config, "hidden_state");
|
||||||
if (bindings) {
|
|
||||||
int length = json_object_array_length(bindings);
|
|
||||||
for (int i = 0; i < length; ++i) {
|
|
||||||
json_object *bindobj = json_object_array_get_idx(bindings, i);
|
|
||||||
struct swaybar_binding *binding =
|
|
||||||
calloc(1, sizeof(struct swaybar_binding));
|
|
||||||
binding->button = json_object_get_int(
|
|
||||||
json_object_object_get(bindobj, "event_code"));
|
|
||||||
binding->command = strdup(json_object_get_string(
|
|
||||||
json_object_object_get(bindobj, "command")));
|
|
||||||
binding->release = json_object_get_boolean(
|
|
||||||
json_object_object_get(bindobj, "release"));
|
|
||||||
list_add(config->bindings, binding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hidden_state) {
|
if (hidden_state) {
|
||||||
free(config->hidden_state);
|
free(config->hidden_state);
|
||||||
config->hidden_state = strdup(json_object_get_string(hidden_state));
|
config->hidden_state = strdup(json_object_get_string(hidden_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_object *mode = json_object_object_get(bar_config, "mode");
|
||||||
if (mode) {
|
if (mode) {
|
||||||
free(config->mode);
|
free(config->mode);
|
||||||
config->mode = strdup(json_object_get_string(mode));
|
config->mode = strdup(json_object_get_string(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_object *outputs = json_object_object_get(bar_config, "outputs");
|
||||||
struct config_output *output, *tmp;
|
struct config_output *output, *tmp;
|
||||||
wl_list_for_each_safe(output, tmp, &config->outputs, link) {
|
wl_list_for_each_safe(output, tmp, &config->outputs, link) {
|
||||||
wl_list_remove(&output->link);
|
wl_list_remove(&output->link);
|
||||||
|
@ -295,40 +272,115 @@ static bool ipc_parse_config(
|
||||||
json_object *output = json_object_array_get_idx(outputs, i);
|
json_object *output = json_object_array_get_idx(outputs, i);
|
||||||
const char *name = json_object_get_string(output);
|
const char *name = json_object_get_string(output);
|
||||||
if (strcmp("*", name) == 0) {
|
if (strcmp("*", name) == 0) {
|
||||||
config->all_outputs = true;
|
struct config_output *coutput, *tmp;
|
||||||
|
wl_list_for_each_safe(coutput, tmp, &config->outputs, link) {
|
||||||
|
wl_list_remove(&coutput->link);
|
||||||
|
free(coutput->name);
|
||||||
|
free(coutput);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
struct config_output *coutput = calloc(
|
struct config_output *coutput = calloc(
|
||||||
1, sizeof(struct config_output));
|
1, sizeof(struct config_output));
|
||||||
coutput->name = strdup(name);
|
coutput->name = strdup(name);
|
||||||
coutput->index = SIZE_MAX;
|
|
||||||
wl_list_insert(&config->outputs, &coutput->link);
|
wl_list_insert(&config->outputs, &coutput->link);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
config->all_outputs = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colors) {
|
json_object *pango_markup =
|
||||||
ipc_parse_colors(config, colors);
|
json_object_object_get(bar_config, "pango_markup");
|
||||||
|
if (pango_markup) {
|
||||||
|
config->pango_markup = json_object_get_boolean(pango_markup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_object *position = json_object_object_get(bar_config, "position");
|
||||||
|
if (position) {
|
||||||
|
config->position = parse_position(json_object_get_string(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *separator_symbol =
|
||||||
|
json_object_object_get(bar_config, "separator_symbol");
|
||||||
|
if (separator_symbol) {
|
||||||
|
free(config->sep_symbol);
|
||||||
|
config->sep_symbol = strdup(json_object_get_string(separator_symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *status_command =
|
||||||
|
json_object_object_get(bar_config, "status_command");
|
||||||
|
if (status_command) {
|
||||||
|
const char *command = json_object_get_string(status_command);
|
||||||
|
free(config->status_command);
|
||||||
|
config->status_command = strdup(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *status_edge_padding =
|
||||||
|
json_object_object_get(bar_config, "status_edge_padding");
|
||||||
|
if (status_edge_padding) {
|
||||||
|
config->status_edge_padding = json_object_get_int(status_edge_padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *status_padding =
|
||||||
|
json_object_object_get(bar_config, "status_padding");
|
||||||
|
if (status_padding) {
|
||||||
|
config->status_padding = json_object_get_int(status_padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *strip_workspace_name =
|
||||||
|
json_object_object_get(bar_config, "strip_workspace_name");
|
||||||
|
if (strip_workspace_name) {
|
||||||
|
config->strip_workspace_name =
|
||||||
|
json_object_get_boolean(strip_workspace_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *strip_workspace_numbers =
|
||||||
|
json_object_object_get(bar_config, "strip_workspace_numbers");
|
||||||
|
if (strip_workspace_numbers) {
|
||||||
|
config->strip_workspace_numbers =
|
||||||
|
json_object_get_boolean(strip_workspace_numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *workspace_buttons =
|
||||||
|
json_object_object_get(bar_config, "workspace_buttons");
|
||||||
|
if (workspace_buttons) {
|
||||||
|
config->workspace_buttons = json_object_get_boolean(workspace_buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *wrap_scroll = json_object_object_get(bar_config, "wrap_scroll");
|
||||||
|
if (wrap_scroll) {
|
||||||
|
config->wrap_scroll = json_object_get_boolean(wrap_scroll);
|
||||||
|
}
|
||||||
#if HAVE_TRAY
|
#if HAVE_TRAY
|
||||||
json_object *tray_outputs, *tray_padding, *tray_bindings, *icon_theme;
|
json_object *tray_outputs, *tray_padding, *tray_bindings, *icon_theme;
|
||||||
|
|
||||||
|
if (config->tray_outputs && config->tray_outputs->length) {
|
||||||
|
list_free_items_and_destroy(config->tray_outputs);
|
||||||
|
}
|
||||||
if ((json_object_object_get_ex(bar_config, "tray_outputs", &tray_outputs))) {
|
if ((json_object_object_get_ex(bar_config, "tray_outputs", &tray_outputs))) {
|
||||||
config->tray_outputs = create_list();
|
config->tray_outputs = create_list();
|
||||||
int length = json_object_array_length(tray_outputs);
|
int length = json_object_array_length(tray_outputs);
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
json_object *o = json_object_array_get_idx(tray_outputs, i);
|
json_object *output= json_object_array_get_idx(tray_outputs, i);
|
||||||
list_add(config->tray_outputs, strdup(json_object_get_string(o)));
|
const char *name = json_object_get_string(output);
|
||||||
|
if (strcmp(name, "none") == 0) {
|
||||||
|
config->tray_hidden = true;
|
||||||
|
list_free_items_and_destroy(config->tray_outputs);
|
||||||
|
config->tray_outputs = create_list();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
list_add(config->tray_outputs, strdup(name));
|
||||||
}
|
}
|
||||||
config->tray_hidden = strcmp(config->tray_outputs->items[0], "none") == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((json_object_object_get_ex(bar_config, "tray_padding", &tray_padding))) {
|
if ((json_object_object_get_ex(bar_config, "tray_padding", &tray_padding))) {
|
||||||
config->tray_padding = json_object_get_int(tray_padding);
|
config->tray_padding = json_object_get_int(tray_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct tray_binding *tray_bind = NULL, *tmp_tray_bind = NULL;
|
||||||
|
wl_list_for_each_safe(tray_bind, tmp_tray_bind, &config->tray_bindings,
|
||||||
|
link) {
|
||||||
|
wl_list_remove(&tray_bind->link);
|
||||||
|
free_tray_binding(tray_bind);
|
||||||
|
}
|
||||||
if ((json_object_object_get_ex(bar_config, "tray_bindings", &tray_bindings))) {
|
if ((json_object_object_get_ex(bar_config, "tray_bindings", &tray_bindings))) {
|
||||||
int length = json_object_array_length(tray_bindings);
|
int length = json_object_array_length(tray_bindings);
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
|
@ -423,41 +475,6 @@ bool ipc_get_workspaces(struct swaybar *bar) {
|
||||||
return determine_bar_visibility(bar, false);
|
return determine_bar_visibility(bar, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ipc_get_outputs(struct swaybar *bar) {
|
|
||||||
uint32_t len = 0;
|
|
||||||
char *res = ipc_single_command(bar->ipc_socketfd,
|
|
||||||
IPC_GET_OUTPUTS, NULL, &len);
|
|
||||||
json_object *outputs = json_tokener_parse(res);
|
|
||||||
for (size_t i = 0; i < json_object_array_length(outputs); ++i) {
|
|
||||||
json_object *output = json_object_array_get_idx(outputs, i);
|
|
||||||
json_object *output_name, *output_active;
|
|
||||||
json_object_object_get_ex(output, "name", &output_name);
|
|
||||||
json_object_object_get_ex(output, "active", &output_active);
|
|
||||||
const char *name = json_object_get_string(output_name);
|
|
||||||
bool active = json_object_get_boolean(output_active);
|
|
||||||
if (!active) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (bar->config->all_outputs) {
|
|
||||||
struct config_output *coutput =
|
|
||||||
calloc(1, sizeof(struct config_output));
|
|
||||||
coutput->name = strdup(name);
|
|
||||||
coutput->index = i;
|
|
||||||
wl_list_insert(&bar->config->outputs, &coutput->link);
|
|
||||||
} else {
|
|
||||||
struct config_output *coutput;
|
|
||||||
wl_list_for_each(coutput, &bar->config->outputs, link) {
|
|
||||||
if (strcmp(name, coutput->name) == 0) {
|
|
||||||
coutput->index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json_object_put(outputs);
|
|
||||||
free(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) {
|
void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) {
|
||||||
sway_log(SWAY_DEBUG, "Executing binding for button %u (release=%d): `%s`",
|
sway_log(SWAY_DEBUG, "Executing binding for button %u (release=%d): `%s`",
|
||||||
bind->button, bind->release, bind->command);
|
bind->button, bind->release, bind->command);
|
||||||
|
@ -475,7 +492,6 @@ bool ipc_initialize(struct swaybar *bar) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
free(res);
|
free(res);
|
||||||
ipc_get_outputs(bar);
|
|
||||||
|
|
||||||
struct swaybar_config *config = bar->config;
|
struct swaybar_config *config = bar->config;
|
||||||
char subscribe[128]; // suitably large buffer
|
char subscribe[128]; // suitably large buffer
|
||||||
|
@ -509,56 +525,87 @@ static bool handle_bar_state_update(struct swaybar *bar, json_object *event) {
|
||||||
return determine_bar_visibility(bar, false);
|
return determine_bar_visibility(bar, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool handle_barconfig_update(struct swaybar *bar,
|
static bool handle_barconfig_update(struct swaybar *bar, const char *payload,
|
||||||
json_object *json_config) {
|
json_object *json_config) {
|
||||||
json_object *json_id;
|
json_object *json_id = json_object_object_get(json_config, "id");
|
||||||
json_object_object_get_ex(json_config, "id", &json_id);
|
|
||||||
const char *id = json_object_get_string(json_id);
|
const char *id = json_object_get_string(json_id);
|
||||||
if (strcmp(id, bar->id) != 0) {
|
if (strcmp(id, bar->id) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct swaybar_config *config = bar->config;
|
struct swaybar_config *newcfg = init_config();
|
||||||
|
ipc_parse_config(newcfg, payload);
|
||||||
|
|
||||||
json_object *json_state;
|
struct swaybar_config *oldcfg = bar->config;
|
||||||
json_object_object_get_ex(json_config, "hidden_state", &json_state);
|
bar->config = newcfg;
|
||||||
const char *new_state = json_object_get_string(json_state);
|
|
||||||
char *old_state = config->hidden_state;
|
|
||||||
if (strcmp(new_state, old_state) != 0) {
|
|
||||||
sway_log(SWAY_DEBUG, "Changing bar hidden state to %s", new_state);
|
|
||||||
free(old_state);
|
|
||||||
config->hidden_state = strdup(new_state);
|
|
||||||
return determine_bar_visibility(bar, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(config->mode);
|
struct swaybar_output *output, *tmp_output;
|
||||||
json_object *json_mode;
|
wl_list_for_each_safe(output, tmp_output, &bar->outputs, link) {
|
||||||
json_object_object_get_ex(json_config, "mode", &json_mode);
|
bool found = wl_list_empty(&newcfg->outputs);
|
||||||
config->mode = strdup(json_object_get_string(json_mode));
|
struct config_output *coutput;
|
||||||
sway_log(SWAY_DEBUG, "Changing bar mode to %s", config->mode);
|
wl_list_for_each(coutput, &newcfg->outputs, link) {
|
||||||
|
if (strcmp(coutput->name, output->name) == 0 ||
|
||||||
json_object *gaps;
|
strcmp(coutput->name, output->identifier) == 0) {
|
||||||
json_object_object_get_ex(json_config, "gaps", &gaps);
|
found = true;
|
||||||
if (gaps) {
|
break;
|
||||||
json_object *top = json_object_object_get(gaps, "top");
|
|
||||||
if (top) {
|
|
||||||
config->gaps.top = json_object_get_int(top);
|
|
||||||
}
|
}
|
||||||
json_object *right = json_object_object_get(gaps, "right");
|
|
||||||
if (right) {
|
|
||||||
config->gaps.right = json_object_get_int(right);
|
|
||||||
}
|
}
|
||||||
json_object *bottom = json_object_object_get(gaps, "bottom");
|
if (!found) {
|
||||||
if (bottom) {
|
destroy_layer_surface(output);
|
||||||
config->gaps.bottom = json_object_get_int(bottom);
|
wl_list_remove(&output->link);
|
||||||
|
wl_list_insert(&bar->unused_outputs, &output->link);
|
||||||
|
} else if (!oldcfg->font || !newcfg->font ||
|
||||||
|
strcmp(oldcfg->font, newcfg->font) != 0) {
|
||||||
|
output->height = 0; // force update height
|
||||||
}
|
}
|
||||||
json_object *left = json_object_object_get(gaps, "left");
|
}
|
||||||
if (left) {
|
wl_list_for_each_safe(output, tmp_output, &bar->unused_outputs, link) {
|
||||||
config->gaps.left = json_object_get_int(left);
|
bool found = wl_list_empty(&newcfg->outputs);
|
||||||
|
struct config_output *coutput;
|
||||||
|
wl_list_for_each(coutput, &newcfg->outputs, link) {
|
||||||
|
if (strcmp(coutput->name, output->name) == 0 ||
|
||||||
|
strcmp(coutput->name, output->identifier) == 0) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
wl_list_remove(&output->link);
|
||||||
|
wl_list_insert(&bar->outputs, &output->link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return determine_bar_visibility(bar, true);
|
if (bar->status && (!newcfg->status_command ||
|
||||||
|
strcmp(newcfg->status_command, oldcfg->status_command) != 0)) {
|
||||||
|
status_line_free(bar->status);
|
||||||
|
bar->status = NULL;
|
||||||
|
}
|
||||||
|
if (!bar->status && newcfg->status_command) {
|
||||||
|
bar->status = status_line_init(newcfg->status_command);
|
||||||
|
bar->status->bar = bar;
|
||||||
|
loop_add_fd(bar->eventloop, bar->status->read_fd, POLLIN,
|
||||||
|
status_in, bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_TRAY
|
||||||
|
if (oldcfg->tray_hidden && !newcfg->tray_hidden) {
|
||||||
|
bar->tray = create_tray(bar);
|
||||||
|
loop_add_fd(bar->eventloop, bar->tray->fd, POLLIN, tray_in,
|
||||||
|
bar->tray->bus);
|
||||||
|
} else if (bar->tray && newcfg->tray_hidden) {
|
||||||
|
loop_remove_fd(bar->eventloop, bar->tray->fd);
|
||||||
|
destroy_tray(bar->tray);
|
||||||
|
bar->tray = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (newcfg->workspace_buttons) {
|
||||||
|
ipc_get_workspaces(bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_config(oldcfg);
|
||||||
|
determine_bar_visibility(bar, true);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_ipc_readable(struct swaybar *bar) {
|
bool handle_ipc_readable(struct swaybar *bar) {
|
||||||
|
@ -599,7 +646,7 @@ bool handle_ipc_readable(struct swaybar *bar) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IPC_EVENT_BARCONFIG_UPDATE:
|
case IPC_EVENT_BARCONFIG_UPDATE:
|
||||||
bar_is_dirty = handle_barconfig_update(bar, result);
|
bar_is_dirty = handle_barconfig_update(bar, resp->payload, result);
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_BAR_STATE_UPDATE:
|
case IPC_EVENT_BAR_STATE_UPDATE:
|
||||||
bar_is_dirty = handle_bar_state_update(bar, result);
|
bar_is_dirty = handle_bar_state_update(bar, result);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "loop.h"
|
#include "loop.h"
|
||||||
|
@ -174,6 +176,7 @@ struct status_line *status_line_init(char *cmd) {
|
||||||
void status_line_free(struct status_line *status) {
|
void status_line_free(struct status_line *status) {
|
||||||
status_line_close_fds(status);
|
status_line_close_fds(status);
|
||||||
kill(status->pid, SIGTERM);
|
kill(status->pid, SIGTERM);
|
||||||
|
waitpid(status->pid, NULL, 0);
|
||||||
if (status->protocol == PROTOCOL_I3BAR) {
|
if (status->protocol == PROTOCOL_I3BAR) {
|
||||||
struct i3bar_block *block, *tmp;
|
struct i3bar_block *block, *tmp;
|
||||||
wl_list_for_each_safe(block, tmp, &status->blocks, link) {
|
wl_list_for_each_safe(block, tmp, &status->blocks, link) {
|
||||||
|
|
Loading…
Reference in a new issue