-
-
Save Lokaltog/9191303 to your computer and use it in GitHub Desktop.
Dump window manager info to JSON (for usage with wkline)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fcntl.h> | |
#include <gdk/gdk.h> | |
#include <gdk/gdkx.h> | |
#include <glib.h> | |
#include <gtk/gtk.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/stat.h> | |
#include <webkit/webkit.h> | |
#include <xcb/xcb.h> | |
#include <xcb/xcb_atom.h> | |
#include <xcb/xcb_ewmh.h> // dependency on xcb-util-wm | |
#include <jansson.h> | |
#ifndef MIN | |
#define MIN(A, B) ((A) < (B) ? (A) : (B)) | |
#endif | |
#define PROPERTY_MAX_LEN 256 | |
#define DESKTOP_MAX_LEN 10 | |
typedef struct desktop_t { | |
bool is_selected; | |
bool is_urgent; | |
bool is_valid; | |
int clients_len; | |
} desktop_t; | |
bool | |
get_active_window_name(xcb_ewmh_connection_t *ewmh, int screen_nbr, char *window_name) { | |
xcb_window_t active_window; | |
xcb_ewmh_get_utf8_strings_reply_t window_data; | |
size_t len; | |
if (! xcb_ewmh_get_active_window_reply(ewmh, xcb_ewmh_get_active_window_unchecked(ewmh, screen_nbr), &active_window, NULL)) { | |
fprintf(stderr, "Found no active window\n"); | |
return false; | |
} | |
if (! xcb_ewmh_get_wm_name_reply(ewmh, xcb_ewmh_get_wm_name_unchecked(ewmh, active_window), &window_data, NULL)) { | |
fprintf(stderr, "Could not read WM_NAME from active window\n"); | |
return false; | |
} | |
len = MIN(PROPERTY_MAX_LEN, window_data.strings_len + 1); | |
memcpy(window_name, window_data.strings, len); | |
window_name[len] = 0; | |
xcb_ewmh_get_utf8_strings_reply_wipe(&window_data); | |
return true; | |
} | |
bool | |
get_desktop_list(xcb_ewmh_connection_t *ewmh, int screen_nbr, desktop_t *desktops) { | |
unsigned short i; | |
uint32_t desktop_curr, desktop_len, client_desktop; | |
xcb_ewmh_get_windows_reply_t clients; | |
// get current desktop | |
if (! xcb_ewmh_get_current_desktop_reply(ewmh, xcb_ewmh_get_current_desktop_unchecked(ewmh, screen_nbr), &desktop_curr, NULL)) { | |
fprintf(stderr, "Could not get current desktop\n"); | |
return false; | |
} | |
// get desktop count | |
if (! xcb_ewmh_get_number_of_desktops_reply(ewmh, xcb_ewmh_get_number_of_desktops_unchecked(ewmh, screen_nbr), &desktop_len, NULL)) { | |
fprintf(stderr, "Could not get desktop count\n"); | |
return false; | |
} | |
for (i = 0; i < desktop_len; i++) { | |
desktops[i].is_selected = i == desktop_curr; | |
desktops[i].is_valid = true; | |
} | |
// get clients | |
if (! xcb_ewmh_get_client_list_reply(ewmh, xcb_ewmh_get_client_list_unchecked(ewmh, screen_nbr), &clients, NULL)) { | |
fprintf(stderr, "Could not get client list\n"); | |
return false; | |
} | |
for (i = 0; i < clients.windows_len; i++) { | |
if (! xcb_ewmh_get_wm_desktop_reply(ewmh, xcb_ewmh_get_wm_desktop_unchecked(ewmh, clients.windows[i]), &client_desktop, NULL)) { | |
continue; | |
} | |
desktops[client_desktop].clients_len++; | |
// TODO check urgent hint and assign to desktop | |
} | |
xcb_ewmh_get_windows_reply_wipe(&clients); | |
return true; | |
} | |
int | |
main (int argc, char *argv[]) { | |
xcb_connection_t *conn; | |
int screen_nbr = 0; | |
conn = xcb_connect(NULL, &screen_nbr); | |
xcb_ewmh_connection_t ewmh; | |
xcb_intern_atom_cookie_t *ewmh_cookie = xcb_ewmh_init_atoms(conn, &ewmh); | |
xcb_ewmh_init_atoms_replies(&ewmh, ewmh_cookie, NULL); | |
char active_window_name[PROPERTY_MAX_LEN]; | |
get_active_window_name(&ewmh, screen_nbr, active_window_name); | |
desktop_t desktops[DESKTOP_MAX_LEN] = {}; | |
get_desktop_list(&ewmh, screen_nbr, desktops); | |
unsigned short i; | |
json_t *json_desktop_object = json_object(); | |
json_t *json_desktops_array = json_array(); | |
json_object_set_new(json_desktop_object, "current_window", json_string(active_window_name)); | |
json_object_set_new(json_desktop_object, "desktops", json_desktops_array); | |
for (i = 0; i < DESKTOP_MAX_LEN; i++) { | |
if (! desktops[i].is_valid) { | |
break; | |
} | |
json_t *json_desktop = json_object(); | |
json_object_set_new(json_desktop, "clients_len", json_integer(desktops[i].clients_len)); | |
json_array_append_new(json_desktops_array, json_desktop); | |
if (desktops[i].is_selected) { | |
json_object_set_new(json_desktop_object, "current_desktop", json_integer(i)); | |
} | |
} | |
char *json_payload = json_dumps(json_desktop_object, 0); | |
printf("%s", json_payload); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment