Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Bar mode/hidden_state events #2751

Merged
merged 14 commits into from
Oct 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ enum ipc_command_type {
IPC_EVENT_BINDING = ((1<<31) | 5),
IPC_EVENT_SHUTDOWN = ((1<<31) | 6),
IPC_EVENT_TICK = ((1<<31) | 7),

// sway-specific event types
IPC_EVENT_BAR_STATE_UPDATE = ((1<<31) | 20),
};

#endif
1 change: 1 addition & 0 deletions include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ struct bar_config {
* In "show" mode, it will always be shown on top of the active workspace.
*/
char *hidden_state;
bool visible_by_modifier; // only relevant in "hide" mode
/**
* Id name used to identify the bar through IPC.
*
Expand Down
1 change: 1 addition & 0 deletions include/sway/ipc-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void ipc_event_workspace(struct sway_workspace *old,
struct sway_workspace *new, const char *change);
void ipc_event_window(struct sway_container *window, const char *change);
void ipc_event_barconfig_update(struct bar_config *bar);
void ipc_event_bar_state_update(struct bar_config *bar);
void ipc_event_mode(const char *mode, bool pango);
void ipc_event_shutdown(const char *reason);
void ipc_event_binding(struct sway_binding *binding);
Expand Down
37 changes: 30 additions & 7 deletions include/swaybar/bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ enum hotspot_event_handling {
};

struct swaybar_hotspot {
struct wl_list link;
struct wl_list link; // swaybar_output::hotspots
int x, y, width, height;
enum hotspot_event_handling (*callback)(struct swaybar_output *output,
int x, int y, enum x11_button button, void *data);
Expand All @@ -46,6 +46,15 @@ struct swaybar_hotspot {
};

struct swaybar {
char *id;
char *mode;
bool mode_pango_markup;

// only relevant when bar is in "hide" mode
bool visible_by_modifier;
bool visible_by_urgency;
bool visible;

struct wl_display *display;
struct wl_compositor *compositor;
struct zwlr_layer_shell_v1 *layer_shell;
Expand All @@ -60,20 +69,20 @@ struct swaybar {
int ipc_event_socketfd;
int ipc_socketfd;

struct wl_list outputs;
struct wl_list outputs; // swaybar_output::link
};

struct swaybar_output {
struct wl_list link;
struct wl_list link; // swaybar::outputs
struct swaybar *bar;
struct wl_output *output;
struct zxdg_output_v1 *xdg_output;
struct wl_surface *surface;
struct zwlr_layer_surface_v1 *layer_surface;
uint32_t wl_name;

struct wl_list workspaces;
struct wl_list hotspots;
struct wl_list workspaces; // swaybar_workspace::link
struct wl_list hotspots; // swaybar_hotspot::link

char *name;
bool focused;
Expand All @@ -88,18 +97,32 @@ struct swaybar_output {
};

struct swaybar_workspace {
struct wl_list link;
struct wl_list link; // swaybar_output::workspaces
int num;
char *name;
bool focused;
bool visible;
bool urgent;
};

bool bar_setup(struct swaybar *bar, const char *socket_path, const char *bar_id);
bool bar_setup(struct swaybar *bar, const char *socket_path);
void bar_run(struct swaybar *bar);
void bar_teardown(struct swaybar *bar);

/*
* Determines whether the bar should be visible and changes it to be so.
* If the current visibility of the bar is the different to what it should be,
* then it adds or destroys the layer surface as required,
* as well as sending the cont or stop signal to the status command.
* If the current visibility of the bar is already what it should be,
* then this function is a no-op, unless moving_layer is true, which occurs
* when the bar changes from "hide" to "dock" mode or vice versa, and the bar
* needs to be destroyed and re-added in order to change its layer.
*
* Returns true if the bar is now visible, otherwise false.
*/
bool determine_bar_visibility(struct swaybar *bar, bool moving_layer);
void free_hotspots(struct wl_list *list);
void free_workspaces(struct wl_list *list);

#endif
5 changes: 3 additions & 2 deletions include/swaybar/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct box_colors {
};

struct config_output {
struct wl_list link;
struct wl_list link; // swaybar_config::outputs
char *name;
size_t index;
};
Expand All @@ -31,7 +31,8 @@ struct swaybar_config {
char *font;
char *sep_symbol;
char *mode;
bool mode_pango_markup;
char *hidden_state;
char *modifier;
bool strip_workspace_numbers;
bool binding_mode_indicator;
bool wrap_scroll;
Expand Down
2 changes: 1 addition & 1 deletion include/swaybar/i3bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "status_line.h"

struct i3bar_block {
struct wl_list link;
struct wl_list link; // status_link::blocks
int ref_count;
char *full_text, *short_text, *align;
bool urgent;
Expand Down
4 changes: 2 additions & 2 deletions include/swaybar/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#include <stdbool.h>
#include "swaybar/bar.h"

bool ipc_initialize(struct swaybar *bar, const char *bar_id);
bool ipc_initialize(struct swaybar *bar);
bool handle_ipc_readable(struct swaybar *bar);
void ipc_get_workspaces(struct swaybar *bar);
bool ipc_get_workspaces(struct swaybar *bar);
void ipc_send_workspace_command(struct swaybar *bar, const char *ws);
void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind);

Expand Down
3 changes: 3 additions & 0 deletions include/swaybar/status_line.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ struct status_line {
const char *text;
struct wl_list blocks; // i3bar_block::link

int stop_signal;
int cont_signal;

bool click_events;
bool clicked;
char *buffer;
Expand Down
34 changes: 15 additions & 19 deletions sway/commands/bar/hidden_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static struct cmd_results *bar_set_hidden_state(struct bar_config *bar,
}
// free old mode
free(old_state);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
return NULL;
}

struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) {
Expand All @@ -50,24 +50,20 @@ struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) {

const char *state = argv[0];
if (config->reading) {
return bar_set_hidden_state(config->current_bar, state);
}

const char *id = NULL;
if (argc == 2) {
id = argv[1];
}
struct bar_config *bar;
for (int i = 0; i < config->bars->length; ++i) {
bar = config->bars->items[i];
if (id && strcmp(id, bar->id) == 0) {
return bar_set_hidden_state(bar, state);
}

error = bar_set_hidden_state(bar, state);
if (error) {
return error;
error = bar_set_hidden_state(config->current_bar, state);
} else {
const char *id = argc == 2 ? argv[1] : NULL;
for (int i = 0; i < config->bars->length; ++i) {
struct bar_config *bar = config->bars->items[i];
if (id) {
if (strcmp(id, bar->id) == 0) {
error = bar_set_hidden_state(bar, state);
break;
}
} else if ((error = bar_set_hidden_state(bar, state))) {
break;
}
}
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
34 changes: 15 additions & 19 deletions sway/commands/bar/mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode

// free old mode
free(old_mode);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
return NULL;
}

struct cmd_results *bar_cmd_mode(int argc, char **argv) {
Expand All @@ -51,24 +51,20 @@ struct cmd_results *bar_cmd_mode(int argc, char **argv) {

const char *mode = argv[0];
if (config->reading) {
return bar_set_mode(config->current_bar, mode);
}

const char *id = NULL;
if (argc == 2) {
id = argv[1];
}

struct bar_config *bar;
for (int i = 0; i < config->bars->length; ++i) {
bar = config->bars->items[i];
if (id && strcmp(id, bar->id) == 0) {
return bar_set_mode(bar, mode);
}
error = bar_set_mode(bar, mode);
if (error) {
return error;
error = bar_set_mode(config->current_bar, mode);
} else {
const char *id = argc == 2 ? argv[1] : NULL;
for (int i = 0; i < config->bars->length; ++i) {
struct bar_config *bar = config->bars->items[i];
if (id) {
if (strcmp(id, bar->id) == 0) {
error = bar_set_mode(bar, mode);
break;
}
} else if ((error = bar_set_mode(bar, mode))) {
break;
}
}
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
2 changes: 2 additions & 0 deletions sway/config/bar.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "stringop.h"
#include "list.h"
#include "log.h"
#include "util.h"

static void terminate_swaybar(pid_t pid) {
wlr_log(WLR_DEBUG, "Terminating swaybar %d", pid);
Expand Down Expand Up @@ -101,6 +102,7 @@ struct bar_config *default_bar_config(void) {
bar->binding_mode_indicator = true;
bar->verbose = false;
bar->pid = 0;
bar->modifier = get_modifier_mask_by_name("Mod4");
if (!(bar->mode = strdup("dock"))) {
goto cleanup;
}
Expand Down
28 changes: 22 additions & 6 deletions sway/input/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "sway/input/input-manager.h"
#include "sway/input/keyboard.h"
#include "sway/input/seat.h"
#include "sway/ipc-server.h"
#include "log.h"

/**
Expand Down Expand Up @@ -66,10 +67,10 @@ static void update_shortcut_state(struct sway_shortcut_state *state,
bool last_key_was_a_modifier = raw_modifiers != state->last_raw_modifiers;
state->last_raw_modifiers = raw_modifiers;

if (last_key_was_a_modifier && state->last_keycode) {
// Last pressed key before this one was a modifier
state_erase_key(state, state->last_keycode);
}
if (last_key_was_a_modifier && state->last_keycode) {
// Last pressed key before this one was a modifier
state_erase_key(state, state->last_keycode);
}

if (event->state == WLR_KEY_PRESSED) {
// Add current key to set; there may be duplicates
Expand Down Expand Up @@ -235,7 +236,6 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
code_modifiers);
}


bool handled = false;

// Identify active release binding
Expand Down Expand Up @@ -337,6 +337,19 @@ static int handle_keyboard_repeat(void *data) {
return 0;
}

static void determine_bar_visibility(uint32_t modifiers) {
for (int i = 0; i < config->bars->length; ++i) {
struct bar_config *bar = config->bars->items[i];
if (strcmp(bar->mode, bar->hidden_state) == 0) { // both are "hide"
bool should_be_visible = (~modifiers & bar->modifier) == 0;
if (bar->visible_by_modifier != should_be_visible) {
bar->visible_by_modifier = should_be_visible;
ipc_event_bar_state_update(bar);
}
}
}
}

static void handle_keyboard_modifiers(struct wl_listener *listener,
void *data) {
struct sway_keyboard *keyboard =
Expand All @@ -346,6 +359,9 @@ static void handle_keyboard_modifiers(struct wl_listener *listener,
keyboard->seat_device->input_device->wlr_device;
wlr_seat_set_keyboard(wlr_seat, wlr_device);
wlr_seat_keyboard_notify_modifiers(wlr_seat, &wlr_device->keyboard->modifiers);

uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard);
determine_bar_visibility(modifiers);
}

struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
Expand Down Expand Up @@ -464,7 +480,7 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
keyboard->keyboard_key.notify = handle_keyboard_key;

wl_list_remove(&keyboard->keyboard_modifiers.link);
wl_signal_add( &wlr_device->keyboard->events.modifiers,
wl_signal_add(&wlr_device->keyboard->events.modifiers,
&keyboard->keyboard_modifiers);
keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers;
}
Expand Down
18 changes: 18 additions & 0 deletions sway/ipc-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,22 @@ void ipc_event_barconfig_update(struct bar_config *bar) {
json_object_put(json);
}

void ipc_event_bar_state_update(struct bar_config *bar) {
if (!ipc_has_event_listeners(IPC_EVENT_BAR_STATE_UPDATE)) {
return;
}
wlr_log(WLR_DEBUG, "Sending bar_state_update event");

json_object *json = json_object_new_object();
json_object_object_add(json, "id", json_object_new_string(bar->id));
json_object_object_add(json, "visible_by_modifier",
json_object_new_boolean(bar->visible_by_modifier));

const char *json_string = json_object_to_json_string(json);
ipc_send_event(json_string, IPC_EVENT_BAR_STATE_UPDATE);
json_object_put(json);
}

void ipc_event_mode(const char *mode, bool pango) {
if (!ipc_has_event_listeners(IPC_EVENT_MODE)) {
return;
Expand Down Expand Up @@ -651,6 +667,8 @@ void ipc_client_handle_command(struct ipc_client *client) {
client->subscribed_events |= event_mask(IPC_EVENT_WORKSPACE);
} else if (strcmp(event_type, "barconfig_update") == 0) {
client->subscribed_events |= event_mask(IPC_EVENT_BARCONFIG_UPDATE);
} else if (strcmp(event_type, "bar_state_update") == 0) {
client->subscribed_events |= event_mask(IPC_EVENT_BAR_STATE_UPDATE);
} else if (strcmp(event_type, "mode") == 0) {
client->subscribed_events |= event_mask(IPC_EVENT_MODE);
} else if (strcmp(event_type, "shutdown") == 0) {
Expand Down
16 changes: 16 additions & 0 deletions sway/sway-bar.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ Sway allows configuring swaybar in the sway configuration file.
is given, when mouse button _n_ has been released). To disable the default
behavior for a button, use the command _nop_.

*mode* dock|hide|invisible
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
modifier key is pressed, though this behaviour depends on the hidden state.
In _invisible_ mode, it is permanently hidden. Default is _dock_.

*hidden\_state* hide|show
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_.

*modifier* <Modifier>|none
Specifies the modifier key that shows a hidden bar. Default is _Mod4_.

## TRAY

Swaybar provides a system tray where third-party applications may place icons.
Expand Down
Loading