mirror of
https://github.com/vale981/bspwm
synced 2025-03-05 09:51:38 -05:00
Use modifiable strings, handle non-proper strings
This commit is contained in:
parent
42658b0164
commit
937b960f34
1 changed files with 92 additions and 55 deletions
147
bsps.c
147
bsps.c
|
@ -1,7 +1,6 @@
|
|||
#define _BSD_SOURCE
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
|
@ -17,36 +16,37 @@
|
|||
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
#define FIFO_PATH "BSPWM_FIFO"
|
||||
#define NO_VALUE " "
|
||||
#define NAME_SEP "\0"
|
||||
#define FONT_FAMILY "sans-serif"
|
||||
#define FONT_SIZE 11
|
||||
#define HORIZONTAL_PADDING 9
|
||||
#define FIFO_ENV_VAR "BSPWM_FIFO"
|
||||
#define MAX_LEN 256
|
||||
#define NO_VALUE " "
|
||||
#define FONT_FAMILY "sans-serif"
|
||||
#define FONT_SIZE 11
|
||||
#define HORIZ_PADDING 9
|
||||
|
||||
typedef enum {
|
||||
false,
|
||||
true
|
||||
} bool;
|
||||
|
||||
char *desktop_name;
|
||||
char *window_title;
|
||||
char *font_family ;
|
||||
int font_size = FONT_SIZE;
|
||||
char external_infos[BUFSIZ] = NO_VALUE;
|
||||
xcb_window_t curwin;
|
||||
|
||||
char *fifo_path;
|
||||
int fifo_fd, dpy_fd, sel_fd;
|
||||
|
||||
xcb_connection_t *dpy;
|
||||
xcb_ewmh_connection_t ewmh;
|
||||
xcb_screen_t *screen;
|
||||
int default_screen;
|
||||
xcb_window_t cur_win;
|
||||
|
||||
uint16_t screen_width;
|
||||
unsigned int horizontal_padding = HORIZONTAL_PADDING;
|
||||
unsigned int horiz_padding = HORIZ_PADDING;
|
||||
unsigned int cur_desktop, num_desktops;
|
||||
|
||||
char desktop_name[MAX_LEN] = NO_VALUE;
|
||||
char window_title[MAX_LEN] = NO_VALUE;
|
||||
char external_infos[MAX_LEN] = NO_VALUE;
|
||||
|
||||
char font_family[MAX_LEN] = FONT_FAMILY;
|
||||
int font_size = FONT_SIZE;
|
||||
|
||||
char *fifo_path;
|
||||
int fifo_fd, dpy_fd, sel_fd;
|
||||
|
||||
bool running;
|
||||
|
||||
|
@ -66,12 +66,40 @@ double text_width(char *s)
|
|||
return w;
|
||||
}
|
||||
|
||||
void copy_prop(char *dest, char *src, int len, int idx, int num_itm)
|
||||
{
|
||||
if (num_itm < 2) {
|
||||
strncpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
} else {
|
||||
int pos = 0, cnt = 0;
|
||||
while (cnt < idx && cnt < (num_itm - 1) && pos < len) {
|
||||
pos += strlen(src + pos) + 1;
|
||||
cnt++;
|
||||
}
|
||||
if (cnt < idx)
|
||||
copy_prop(dest, src + pos, len - pos, 0, 1);
|
||||
else
|
||||
strncpy(dest, src + pos, sizeof(dest));
|
||||
}
|
||||
}
|
||||
|
||||
void handle_signal(int sig)
|
||||
{
|
||||
if (sig == SIGTERM || sig == SIGINT || sig == SIGHUP)
|
||||
running = false;
|
||||
}
|
||||
|
||||
void update_cur_desktop(void)
|
||||
{
|
||||
xcb_ewmh_get_current_desktop_reply(&ewmh, xcb_ewmh_get_current_desktop(&ewmh, default_screen), &cur_desktop, NULL);
|
||||
}
|
||||
|
||||
void update_num_desktops(void)
|
||||
{
|
||||
xcb_ewmh_get_number_of_desktops_reply(&ewmh, xcb_ewmh_get_number_of_desktops(&ewmh, default_screen), &num_desktops, NULL);
|
||||
}
|
||||
|
||||
void update_window_title(void)
|
||||
{
|
||||
xcb_window_t win;
|
||||
|
@ -80,62 +108,67 @@ void update_window_title(void)
|
|||
uint32_t values[] = {XCB_EVENT_MASK_PROPERTY_CHANGE};
|
||||
uint32_t values_reset[] = {XCB_EVENT_MASK_NO_EVENT};
|
||||
|
||||
free(window_title);
|
||||
ewmh_txt_prop.strings = NULL;
|
||||
icccm_txt_prop.name = NULL;
|
||||
|
||||
if (xcb_ewmh_get_active_window_reply(&ewmh, xcb_ewmh_get_active_window(&ewmh, default_screen), &win, NULL) == 1
|
||||
&& (xcb_ewmh_get_wm_name_reply(&ewmh, xcb_ewmh_get_wm_name(&ewmh, win), &ewmh_txt_prop, NULL) == 1
|
||||
|| xcb_icccm_get_wm_name_reply(dpy, xcb_icccm_get_wm_name(dpy, win), &icccm_txt_prop, NULL) == 1)) {
|
||||
if (ewmh_txt_prop.strings != NULL)
|
||||
window_title = strdup(ewmh_txt_prop.strings);
|
||||
else if (icccm_txt_prop.name != NULL)
|
||||
window_title = strdup(icccm_txt_prop.name);
|
||||
else
|
||||
window_title = strdup(NO_VALUE);
|
||||
if (win != curwin) {
|
||||
xcb_change_window_attributes(dpy, curwin, XCB_CW_EVENT_MASK, values_reset);
|
||||
curwin = win;
|
||||
if (ewmh_txt_prop.strings != NULL && ewmh_txt_prop.strings_len > 0) {
|
||||
copy_prop(window_title, ewmh_txt_prop.strings, ewmh_txt_prop.strings_len, 0, 1);
|
||||
} else if (icccm_txt_prop.name != NULL && icccm_txt_prop.name_len > 0) {
|
||||
copy_prop(window_title, icccm_txt_prop.name, icccm_txt_prop.name_len, 0, 1);
|
||||
} else {
|
||||
strcpy(window_title, NO_VALUE);
|
||||
}
|
||||
if (win != cur_win) {
|
||||
xcb_change_window_attributes(dpy, cur_win, XCB_CW_EVENT_MASK, values_reset);
|
||||
cur_win = win;
|
||||
}
|
||||
xcb_generic_error_t *err = xcb_request_check(dpy, xcb_change_window_attributes_checked(dpy, win, XCB_CW_EVENT_MASK, values));
|
||||
if (err != NULL)
|
||||
running = false;
|
||||
} else {
|
||||
window_title = strdup(NO_VALUE);
|
||||
strcpy(window_title, NO_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
void update_desktop_name(void)
|
||||
{
|
||||
uint32_t cd;
|
||||
/* uint32_t cd; */
|
||||
xcb_ewmh_get_utf8_strings_reply_t names;
|
||||
unsigned int pos = 0, cnt = 0;
|
||||
/* unsigned int pos = 0, cnt = 0; */
|
||||
|
||||
free(desktop_name);
|
||||
|
||||
if (xcb_ewmh_get_current_desktop_reply(&ewmh, xcb_ewmh_get_current_desktop(&ewmh, default_screen), &cd, NULL) == 1 && xcb_ewmh_get_desktop_names_reply(&ewmh, xcb_ewmh_get_desktop_names(&ewmh, default_screen), &names, NULL) == 1) {
|
||||
while (cnt < cd && pos < names.strings_len) {
|
||||
pos += strlen(names.strings + pos) + 1;
|
||||
cnt++;
|
||||
}
|
||||
desktop_name = strdup(names.strings + pos);
|
||||
/* if (xcb_ewmh_get_current_desktop_reply(&ewmh, xcb_ewmh_get_current_desktop(&ewmh, default_screen), &cd, NULL) == 1 && xcb_ewmh_get_desktop_names_reply(&ewmh, xcb_ewmh_get_desktop_names(&ewmh, default_screen), &names, NULL) == 1) { */
|
||||
if (xcb_ewmh_get_desktop_names_reply(&ewmh, xcb_ewmh_get_desktop_names(&ewmh, default_screen), &names, NULL) == 1) {
|
||||
copy_prop(desktop_name, names.strings, names.strings_len, cur_desktop, num_desktops);
|
||||
/* while (cnt < cd && pos < names.strings_len) { */
|
||||
/* pos += strlen(names.strings + pos) + 1; */
|
||||
/* cnt++; */
|
||||
/* } */
|
||||
/* desktop_name = strdup(names.strings + pos); */
|
||||
} else {
|
||||
desktop_name = strdup(NO_VALUE);
|
||||
strcpy(desktop_name, NO_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
void output_infos(void)
|
||||
{
|
||||
double left_width = text_width(desktop_name);
|
||||
double center_width = text_width(window_title);
|
||||
double right_width = text_width(external_infos);
|
||||
double available_center = screen_width - (left_width + right_width + 4 * horizontal_padding);
|
||||
double center_width = text_width(window_title);
|
||||
double available_center = screen_width - (left_width + right_width + 4 * horiz_padding);
|
||||
|
||||
int left_pos = horizontal_padding;
|
||||
int center_pos = left_width + 2 * horizontal_padding + (available_center / 2) - (center_width / 2);
|
||||
int right_pos = screen_width - right_width - horizontal_padding;
|
||||
int left_pos = horiz_padding;
|
||||
int right_pos = screen_width - right_width - horiz_padding;
|
||||
int center_pos = left_width + 2 * horiz_padding + (available_center / 2) - (center_width / 2);
|
||||
|
||||
if (center_width > available_center)
|
||||
center_pos = left_width + 2 * horiz_padding;
|
||||
|
||||
printf("^pa(%i)%s^pa(%i)%s^pa(%i)%s\n", left_pos, desktop_name, center_pos, window_title, right_pos, external_infos);
|
||||
/* printf("^pa(%i)%s^pa(%i)%s^pa(%i)%s\n", left_pos, desktop_name, center_pos, window_title, right_pos, external_infos); */
|
||||
printf("^pa(%i)%s^pa(%i)%s^pa(%i)%s\n", center_pos, window_title, right_pos, external_infos, left_pos, desktop_name);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
@ -145,7 +178,7 @@ void handle_event(xcb_generic_event_t *evt)
|
|||
switch (XCB_EVENT_RESPONSE_TYPE(evt)) {
|
||||
case XCB_PROPERTY_NOTIFY:
|
||||
pne = (xcb_property_notify_event_t *) evt;
|
||||
if (pne->atom == ewmh._NET_CURRENT_DESKTOP || pne->atom == ewmh._NET_DESKTOP_NAMES) {
|
||||
if (pne->atom == ewmh._NET_DESKTOP_NAMES) {
|
||||
update_desktop_name();
|
||||
output_infos();
|
||||
} else if (pne->atom == ewmh._NET_ACTIVE_WINDOW) {
|
||||
|
@ -154,6 +187,12 @@ void handle_event(xcb_generic_event_t *evt)
|
|||
} else if (pne->window != screen->root && (pne->atom == ewmh._NET_WM_NAME || pne->atom == XCB_ATOM_WM_NAME)) {
|
||||
update_window_title();
|
||||
output_infos();
|
||||
} else if (pne->atom == ewmh._NET_NUMBER_OF_DESKTOPS) {
|
||||
update_num_desktops();
|
||||
} else if (pne->atom == ewmh._NET_CURRENT_DESKTOP) {
|
||||
update_cur_desktop();
|
||||
update_desktop_name();
|
||||
output_infos();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
@ -177,16 +216,13 @@ void setup(void)
|
|||
xcb_ewmh_init_atoms_replies(&ewmh, ewmh_cookies, NULL);
|
||||
screen = ewmh.screens[default_screen];
|
||||
screen_width = screen->width_in_pixels;
|
||||
fifo_path = getenv(FIFO_PATH);
|
||||
fifo_path = getenv(FIFO_ENV_VAR);
|
||||
mkfifo(fifo_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
/* http://www.outflux.net/blog/archives/2008/03/09/using-select-on-a-fifo/ */
|
||||
fifo_fd = open(fifo_path, O_RDWR | O_NONBLOCK);
|
||||
dpy_fd = xcb_get_file_descriptor(dpy);
|
||||
sel_fd = MAX(fifo_fd, dpy_fd) + 1;
|
||||
desktop_name = strdup(NO_VALUE);
|
||||
window_title = strdup(NO_VALUE);
|
||||
font_family = strdup(FONT_FAMILY);
|
||||
curwin = 0;
|
||||
cur_win = num_desktops = cur_desktop = 0;
|
||||
running = true;
|
||||
}
|
||||
|
||||
|
@ -199,16 +235,17 @@ int main(int argc, char *argv[])
|
|||
signal(SIGHUP, handle_signal);
|
||||
setup();
|
||||
register_events();
|
||||
update_num_desktops();
|
||||
update_cur_desktop();
|
||||
update_desktop_name();
|
||||
update_window_title();
|
||||
|
||||
if (argc > 1) {
|
||||
free(font_family);
|
||||
font_family = strdup(argv[1]);
|
||||
strncpy(font_family, argv[1], sizeof(font_family));
|
||||
if (argc > 2) {
|
||||
font_size = atoi(argv[2]);
|
||||
if (argc > 3)
|
||||
horizontal_padding = atoi(argv[3]);
|
||||
horiz_padding = atoi(argv[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue