mirror of
https://github.com/swaywm/sway.git
synced 2026-04-26 06:46:26 -04:00
Optionally add focused window title to the bar
Add a "window_title yes|no" bar command that displays the title of the focused window on the bar.
This commit is contained in:
parent
8441711990
commit
8a019a83c9
10 changed files with 131 additions and 1 deletions
|
|
@ -221,6 +221,7 @@ sway_cmd bar_cmd_tray_padding;
|
||||||
sway_cmd bar_cmd_unbindcode;
|
sway_cmd bar_cmd_unbindcode;
|
||||||
sway_cmd bar_cmd_unbindsym;
|
sway_cmd bar_cmd_unbindsym;
|
||||||
sway_cmd bar_cmd_wrap_scroll;
|
sway_cmd bar_cmd_wrap_scroll;
|
||||||
|
sway_cmd bar_cmd_window_title;
|
||||||
sway_cmd bar_cmd_workspace_buttons;
|
sway_cmd bar_cmd_workspace_buttons;
|
||||||
|
|
||||||
sway_cmd bar_colors_cmd_active_workspace;
|
sway_cmd bar_colors_cmd_active_workspace;
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@ struct bar_config {
|
||||||
bool strip_workspace_name;
|
bool strip_workspace_name;
|
||||||
bool binding_mode_indicator;
|
bool binding_mode_indicator;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
|
bool window_title;
|
||||||
struct side_gaps gaps;
|
struct side_gaps gaps;
|
||||||
int status_padding;
|
int status_padding;
|
||||||
int status_edge_padding;
|
int status_edge_padding;
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,12 @@ struct swaybar_config {
|
||||||
char *mode;
|
char *mode;
|
||||||
char *hidden_state;
|
char *hidden_state;
|
||||||
char *modifier;
|
char *modifier;
|
||||||
|
char *title;
|
||||||
bool strip_workspace_numbers;
|
bool strip_workspace_numbers;
|
||||||
bool strip_workspace_name;
|
bool strip_workspace_name;
|
||||||
bool binding_mode_indicator;
|
bool binding_mode_indicator;
|
||||||
bool wrap_scroll;
|
bool wrap_scroll;
|
||||||
|
bool window_title;
|
||||||
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
|
||||||
|
|
@ -51,6 +53,7 @@ struct swaybar_config {
|
||||||
int bottom;
|
int bottom;
|
||||||
int left;
|
int left;
|
||||||
} gaps;
|
} gaps;
|
||||||
|
uint64_t window_app_id;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t background;
|
uint32_t background;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ static struct cmd_handler bar_handlers[] = {
|
||||||
{ "tray_padding", bar_cmd_tray_padding },
|
{ "tray_padding", bar_cmd_tray_padding },
|
||||||
{ "unbindcode", bar_cmd_unbindcode },
|
{ "unbindcode", bar_cmd_unbindcode },
|
||||||
{ "unbindsym", bar_cmd_unbindsym },
|
{ "unbindsym", bar_cmd_unbindsym },
|
||||||
|
{ "window_title", bar_cmd_window_title },
|
||||||
{ "workspace_buttons", bar_cmd_workspace_buttons },
|
{ "workspace_buttons", bar_cmd_workspace_buttons },
|
||||||
{ "wrap_scroll", bar_cmd_wrap_scroll },
|
{ "wrap_scroll", bar_cmd_wrap_scroll },
|
||||||
};
|
};
|
||||||
|
|
|
||||||
22
sway/commands/bar/window_title.c
Normal file
22
sway/commands/bar/window_title.c
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct cmd_results *bar_cmd_window_title(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "window_title", EXPECTED_EQUAL_TO, 1))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
config->current_bar->window_title =
|
||||||
|
parse_boolean(argv[0], config->current_bar->window_title);
|
||||||
|
if (config->current_bar->window_title) {
|
||||||
|
sway_log(SWAY_DEBUG, "Enabling window title on bar: %s",
|
||||||
|
config->current_bar->id);
|
||||||
|
} else {
|
||||||
|
sway_log(SWAY_DEBUG, "Disabling window title on bar: %s",
|
||||||
|
config->current_bar->id);
|
||||||
|
}
|
||||||
|
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||||
|
}
|
||||||
|
|
@ -958,6 +958,8 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
|
||||||
json_object_new_int(bar->status_edge_padding));
|
json_object_new_int(bar->status_edge_padding));
|
||||||
json_object_object_add(json, "wrap_scroll",
|
json_object_object_add(json, "wrap_scroll",
|
||||||
json_object_new_boolean(bar->wrap_scroll));
|
json_object_new_boolean(bar->wrap_scroll));
|
||||||
|
json_object_object_add(json, "window_title",
|
||||||
|
json_object_new_boolean(bar->window_title));
|
||||||
json_object_object_add(json, "workspace_buttons",
|
json_object_object_add(json, "workspace_buttons",
|
||||||
json_object_new_boolean(bar->workspace_buttons));
|
json_object_new_boolean(bar->workspace_buttons));
|
||||||
json_object_object_add(json, "strip_workspace_numbers",
|
json_object_object_add(json, "strip_workspace_numbers",
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ sway_sources = files(
|
||||||
'commands/bar/tray_bind.c',
|
'commands/bar/tray_bind.c',
|
||||||
'commands/bar/tray_output.c',
|
'commands/bar/tray_output.c',
|
||||||
'commands/bar/tray_padding.c',
|
'commands/bar/tray_padding.c',
|
||||||
|
'commands/bar/window_title.c',
|
||||||
'commands/bar/workspace_buttons.c',
|
'commands/bar/workspace_buttons.c',
|
||||||
'commands/bar/wrap_scroll.c',
|
'commands/bar/wrap_scroll.c',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,9 @@ Sway allows configuring swaybar in the sway configuration file.
|
||||||
Enables or disables wrapping when scrolling through workspaces with the
|
Enables or disables wrapping when scrolling through workspaces with the
|
||||||
scroll wheel. Default is _no_.
|
scroll wheel. Default is _no_.
|
||||||
|
|
||||||
|
*window_title* yes|no
|
||||||
|
Enables or disables focused window title on the bar. Default is _no_.
|
||||||
|
|
||||||
*workspace_buttons* yes|no
|
*workspace_buttons* yes|no
|
||||||
Enables or disables workspace buttons on the bar. Default is _yes_.
|
Enables or disables workspace buttons on the bar. Default is _yes_.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,7 @@ static bool ipc_parse_config(
|
||||||
json_object_put(bar_config);
|
json_object_put(bar_config);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
json_object *window_title;
|
||||||
json_object *markup, *mode, *hidden_state, *position, *status_command;
|
json_object *markup, *mode, *hidden_state, *position, *status_command;
|
||||||
json_object *font, *gaps, *bar_height, *wrap_scroll, *workspace_buttons;
|
json_object *font, *gaps, *bar_height, *wrap_scroll, *workspace_buttons;
|
||||||
json_object *strip_workspace_numbers, *strip_workspace_name;
|
json_object *strip_workspace_numbers, *strip_workspace_name;
|
||||||
|
|
@ -186,6 +187,7 @@ static bool ipc_parse_config(
|
||||||
json_object_object_get_ex(bar_config, "gaps", &gaps);
|
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, "bar_height", &bar_height);
|
||||||
json_object_object_get_ex(bar_config, "wrap_scroll", &wrap_scroll);
|
json_object_object_get_ex(bar_config, "wrap_scroll", &wrap_scroll);
|
||||||
|
json_object_object_get_ex(bar_config, "window_title", &window_title);
|
||||||
json_object_object_get_ex(bar_config, "workspace_buttons", &workspace_buttons);
|
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_numbers", &strip_workspace_numbers);
|
||||||
json_object_object_get_ex(bar_config, "strip_workspace_name", &strip_workspace_name);
|
json_object_object_get_ex(bar_config, "strip_workspace_name", &strip_workspace_name);
|
||||||
|
|
@ -226,6 +228,9 @@ static bool ipc_parse_config(
|
||||||
if (wrap_scroll) {
|
if (wrap_scroll) {
|
||||||
config->wrap_scroll = json_object_get_boolean(wrap_scroll);
|
config->wrap_scroll = json_object_get_boolean(wrap_scroll);
|
||||||
}
|
}
|
||||||
|
if (window_title) {
|
||||||
|
config->window_title = json_object_get_boolean(window_title);
|
||||||
|
}
|
||||||
if (workspace_buttons) {
|
if (workspace_buttons) {
|
||||||
config->workspace_buttons = json_object_get_boolean(workspace_buttons);
|
config->workspace_buttons = json_object_get_boolean(workspace_buttons);
|
||||||
}
|
}
|
||||||
|
|
@ -480,7 +485,8 @@ bool ipc_initialize(struct swaybar *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
|
||||||
len = snprintf(subscribe, 128,
|
len = snprintf(subscribe, 128,
|
||||||
"[ \"barconfig_update\" , \"bar_state_update\" %s %s ]",
|
"[ \"barconfig_update\" , \"bar_state_update\" %s %s %s ]",
|
||||||
|
config->window_title ? ", \"window\"" : "",
|
||||||
config->binding_mode_indicator ? ", \"mode\"" : "",
|
config->binding_mode_indicator ? ", \"mode\"" : "",
|
||||||
config->workspace_buttons ? ", \"workspace\"" : "");
|
config->workspace_buttons ? ", \"workspace\"" : "");
|
||||||
free(ipc_single_command(bar->ipc_event_socketfd,
|
free(ipc_single_command(bar->ipc_event_socketfd,
|
||||||
|
|
@ -509,6 +515,49 @@ 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_title_update(struct swaybar *bar,
|
||||||
|
json_object *json_window_event) {
|
||||||
|
json_object *json_container;
|
||||||
|
json_object_object_get_ex(json_window_event, "container",
|
||||||
|
&json_container);
|
||||||
|
struct swaybar_config *config = bar->config;
|
||||||
|
|
||||||
|
json_object *json_change;
|
||||||
|
json_object_object_get_ex(json_window_event, "change", &json_change);
|
||||||
|
const char *change = json_object_get_string(json_change);
|
||||||
|
if (strcmp(change, "close") == 0) {
|
||||||
|
json_object *json_id;
|
||||||
|
json_object_object_get_ex(json_container, "id", &json_id);
|
||||||
|
uint64_t app_id = json_object_get_int64(json_id);
|
||||||
|
if (config->window_app_id == app_id) {
|
||||||
|
// The focused window was closed so remove the title
|
||||||
|
config->window_app_id = 0;
|
||||||
|
if (config->title) {
|
||||||
|
free(config->title);
|
||||||
|
}
|
||||||
|
config->title = NULL;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *json_focused;
|
||||||
|
json_object_object_get_ex(json_container, "focused", &json_focused);
|
||||||
|
if (json_object_get_boolean(json_focused)) {
|
||||||
|
json_object *json_name;
|
||||||
|
json_object_object_get_ex(json_container, "name", &json_name);
|
||||||
|
if (config->title) {
|
||||||
|
free(config->title);
|
||||||
|
}
|
||||||
|
config->title = strdup(json_object_get_string(json_name));
|
||||||
|
json_object *json_id;
|
||||||
|
json_object_object_get_ex(json_container, "id", &json_id);
|
||||||
|
config->window_app_id = json_object_get_int64(json_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool handle_barconfig_update(struct swaybar *bar,
|
static bool handle_barconfig_update(struct swaybar *bar,
|
||||||
json_object *json_config) {
|
json_object *json_config) {
|
||||||
json_object *json_id;
|
json_object *json_id;
|
||||||
|
|
@ -576,6 +625,9 @@ bool handle_ipc_readable(struct swaybar *bar) {
|
||||||
|
|
||||||
bool bar_is_dirty = true;
|
bool bar_is_dirty = true;
|
||||||
switch (resp->type) {
|
switch (resp->type) {
|
||||||
|
case IPC_EVENT_WINDOW:
|
||||||
|
bar_is_dirty = handle_title_update(bar, result);
|
||||||
|
break;
|
||||||
case IPC_EVENT_WORKSPACE:
|
case IPC_EVENT_WORKSPACE:
|
||||||
bar_is_dirty = ipc_get_workspaces(bar);
|
bar_is_dirty = ipc_get_workspaces(bar);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -536,6 +536,45 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo,
|
||||||
return output->height;
|
return output->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t render_window_title(cairo_t *cairo,
|
||||||
|
struct swaybar_output *output, double x) {
|
||||||
|
const char *title = output->bar->config->title;
|
||||||
|
if (!title) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct swaybar_config *config = output->bar->config;
|
||||||
|
int text_width, text_height;
|
||||||
|
get_text_size(cairo, config->font, &text_width, &text_height, NULL,
|
||||||
|
output->scale, output->bar->mode_pango_markup,
|
||||||
|
"%s", title);
|
||||||
|
|
||||||
|
int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale;
|
||||||
|
int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale;
|
||||||
|
int border_width = BORDER_WIDTH * output->scale;
|
||||||
|
|
||||||
|
uint32_t ideal_height = text_height + ws_vertical_padding * 2
|
||||||
|
+ border_width * 2;
|
||||||
|
uint32_t ideal_surface_height = ideal_height / output->scale;
|
||||||
|
if (!output->bar->config->height &&
|
||||||
|
output->height < ideal_surface_height) {
|
||||||
|
return ideal_surface_height;
|
||||||
|
}
|
||||||
|
uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2;
|
||||||
|
|
||||||
|
uint32_t height = output->height * output->scale;
|
||||||
|
cairo_set_source_u32(cairo, config->colors.background);
|
||||||
|
cairo_rectangle(cairo, x, 0, width, height);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
double text_y = height / 2.0 - text_height / 2.0;
|
||||||
|
cairo_set_source_u32(cairo, config->colors.statusline);
|
||||||
|
cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y));
|
||||||
|
pango_printf(cairo, config->font, output->scale,
|
||||||
|
output->bar->mode_pango_markup, "%s", title);
|
||||||
|
return output->height;
|
||||||
|
}
|
||||||
|
|
||||||
static enum hotspot_event_handling workspace_hotspot_callback(
|
static enum hotspot_event_handling workspace_hotspot_callback(
|
||||||
struct swaybar_output *output, struct swaybar_hotspot *hotspot,
|
struct swaybar_output *output, struct swaybar_hotspot *hotspot,
|
||||||
int x, int y, uint32_t button, void *data) {
|
int x, int y, uint32_t button, void *data) {
|
||||||
|
|
@ -660,6 +699,11 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) {
|
||||||
max_height = h > max_height ? h : max_height;
|
max_height = h > max_height ? h : max_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config->window_title) {
|
||||||
|
uint32_t h = render_window_title(cairo, output, x);
|
||||||
|
max_height = h > max_height ? h : max_height;
|
||||||
|
}
|
||||||
|
|
||||||
return max_height > output->height ? max_height : output->height;
|
return max_height > output->height ? max_height : output->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue