13 #include <xcb/xcb_event.h>
14 #include <xcb/xcb_ewmh.h>
17 #define MAX(A, B) ((A) > (B) ? (A) : (B))
19 #define FIFO_PATH "BSPWM_FIFO"
28 char *desktop_name = NO_VALUE;
29 char *window_title = NO_VALUE;
30 char external_info[BUFSIZ] = NO_VALUE;
34 int fifo_fd, dpy_fd, sel_fd;
36 xcb_connection_t *dpy;
37 xcb_ewmh_connection_t ewmh;
45 dpy = xcb_connect(NULL, &default_screen);
46 xcb_intern_atom_cookie_t *ewmh_cookies;
47 ewmh_cookies = xcb_ewmh_init_atoms(dpy, &ewmh);
48 xcb_ewmh_init_atoms_replies(&ewmh, ewmh_cookies, NULL);
49 fifo_path = getenv(FIFO_PATH);
50 mkfifo(fifo_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
51 /* fifo_fd = open(fifo_path, O_RDONLY); */
52 fifo_fd = open(fifo_path, O_RDWR | O_NONBLOCK);
53 /* fprintf(stderr, "fifo_fd %i\n", fifo_fd); */
54 dpy_fd = xcb_get_file_descriptor(dpy);
55 sel_fd = MAX(fifo_fd, dpy_fd) + 1;
60 void register_events(void)
62 xcb_generic_error_t *err;
63 uint32_t values[] = {XCB_EVENT_MASK_PROPERTY_CHANGE};
64 err = xcb_request_check(dpy, xcb_change_window_attributes_checked(dpy, screen->root, XCB_CW_EVENT_MASK, values));
69 void handle_signal(int sig)
71 if (sig == SIGTERM || sig == SIGINT || sig == SIGHUP)
75 void update_window_title(void)
78 xcb_ewmh_get_utf8_strings_reply_t name;
79 xcb_generic_error_t *err;
80 uint32_t values[] = {XCB_EVENT_MASK_PROPERTY_CHANGE};
81 uint32_t values_reset[] = {XCB_EVENT_MASK_NO_EVENT};
83 if (xcb_ewmh_get_active_window_reply(&ewmh, xcb_ewmh_get_active_window(&ewmh, default_screen), &win, NULL) == 1)
85 if (xcb_ewmh_get_wm_name_reply(&ewmh, xcb_ewmh_get_wm_name(&ewmh, win), &name, NULL) == 1) {
86 window_title = strdup(name.strings);
88 xcb_change_window_attributes(dpy, curwin, XCB_CW_EVENT_MASK, values_reset);
91 err = xcb_request_check(dpy, xcb_change_window_attributes_checked(dpy, win, XCB_CW_EVENT_MASK, values));
96 window_title = strdup(NO_VALUE);
101 void update_desktop_name(void)
104 xcb_ewmh_get_utf8_strings_reply_t names;
105 unsigned int pos = 0, cnt = 0;
107 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) {
108 while (cnt < cd && pos < names.strings_len) {
109 pos += strlen(names.strings + pos) + 1;
112 desktop_name = strdup(names.strings + pos);
113 for (cnt = 0; cnt < strlen(desktop_name); cnt++)
114 desktop_name[cnt] = toupper(desktop_name[cnt]);
116 desktop_name = strdup(NO_VALUE);
120 void output_infos(void)
122 printf("\\l %s\\c%s\\r%s \n", desktop_name, window_title, external_info);
126 void handle_event(xcb_generic_event_t *evt)
128 xcb_property_notify_event_t *pne;
129 switch (XCB_EVENT_RESPONSE_TYPE(evt)) {
130 case XCB_PROPERTY_NOTIFY:
131 pne = (xcb_property_notify_event_t *) evt;
132 if (pne->atom == ewmh._NET_CURRENT_DESKTOP) {
133 update_desktop_name();
135 } else if (pne->atom == ewmh._NET_ACTIVE_WINDOW) {
136 update_window_title();
138 } else if (pne->window != screen->root && (pne->atom == ewmh._NET_WM_NAME || pne->atom == XCB_ATOM_WM_NAME)) {
139 update_window_title();
151 xcb_generic_event_t *evt;
152 signal(SIGTERM, handle_signal);
153 signal(SIGINT, handle_signal);
154 signal(SIGHUP, handle_signal);
156 screen = ewmh.screens[default_screen];
158 update_desktop_name();
159 update_window_title();
164 FD_ZERO(&descriptors);
165 FD_SET(fifo_fd, &descriptors);
166 FD_SET(dpy_fd, &descriptors);
168 if (select(sel_fd, &descriptors, NULL, NULL, NULL)) {
169 if (FD_ISSET(dpy_fd, &descriptors)) {
170 while ((evt = xcb_poll_for_event(dpy)) != NULL) {
176 if (FD_ISSET(fifo_fd, &descriptors)) {
177 read(fifo_fd, external_info, sizeof(external_info));