| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 | #include <X11/Xlib.h>#include <X11/Xatom.h>#include <X11/Xutil.h>#undef Bool#undef CursorShape#undef Expose#undef KeyPress#undef KeyRelease#undef FocusIn#undef FocusOut#undef FontChange#undef None#undef Status#undef Unsorted#include <util/platform.h>#include "auto-scene-switcher.hpp"using namespace std;static Display *xdisplay = 0;Display *disp(){	if (!xdisplay)		xdisplay = XOpenDisplay(NULL);	return xdisplay;}void CleanupSceneSwitcher(){	if (!xdisplay)		return;	XCloseDisplay(xdisplay);	xdisplay = 0;}static bool ewmhIsSupported(){	Display *display = disp();	Atom netSupportingWmCheck =		XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", true);	Atom actualType;	int format = 0;	unsigned long num = 0, bytes = 0;	unsigned char *data = NULL;	Window ewmh_window = 0;	int status = XGetWindowProperty(display, DefaultRootWindow(display),					netSupportingWmCheck, 0L, 1L, false,					XA_WINDOW, &actualType, &format, &num,					&bytes, &data);	if (status == Success) {		if (num > 0) {			ewmh_window = ((Window *)data)[0];		}		if (data) {			XFree(data);			data = NULL;		}	}	if (ewmh_window) {		status = XGetWindowProperty(display, ewmh_window,					    netSupportingWmCheck, 0L, 1L, false,					    XA_WINDOW, &actualType, &format,					    &num, &bytes, &data);		if (status != Success || num == 0 ||		    ewmh_window != ((Window *)data)[0]) {			ewmh_window = 0;		}		if (status == Success && data) {			XFree(data);		}	}	return ewmh_window != 0;}static std::vector<Window> getTopLevelWindows(){	std::vector<Window> res;	res.resize(0);	if (!ewmhIsSupported()) {		return res;	}	Atom netClList = XInternAtom(disp(), "_NET_CLIENT_LIST", true);	Atom actualType;	int format;	unsigned long num, bytes;	Window *data = 0;	for (int i = 0; i < ScreenCount(disp()); ++i) {		Window rootWin = RootWindow(disp(), i);		int status = XGetWindowProperty(disp(), rootWin, netClList, 0L,						~0L, false, AnyPropertyType,						&actualType, &format, &num,						&bytes, (uint8_t **)&data);		if (status != Success) {			continue;		}		for (unsigned long i = 0; i < num; ++i)			res.emplace_back(data[i]);		XFree(data);	}	return res;}static std::string GetWindowTitle(size_t i){	Window w = getTopLevelWindows().at(i);	std::string windowTitle;	char *name;	int status = XFetchName(disp(), w, &name);	if (status >= Success && name != nullptr) {		std::string str(name);		windowTitle = str;		XFree(name);	} else {		XTextProperty xtp_new_name;		if (XGetWMName(disp(), w, &xtp_new_name) != 0 &&		    xtp_new_name.value != nullptr) {			std::string str((const char *)xtp_new_name.value);			windowTitle = str;			XFree(xtp_new_name.value);		}	}	return windowTitle;}void GetWindowList(vector<string> &windows){	windows.resize(0);	for (size_t i = 0; i < getTopLevelWindows().size(); ++i) {		if (GetWindowTitle(i) != "")			windows.emplace_back(GetWindowTitle(i));	}}void GetCurrentWindowTitle(string &title){	if (!ewmhIsSupported()) {		return;	}	Atom active = XInternAtom(disp(), "_NET_ACTIVE_WINDOW", true);	Atom actualType;	int format;	unsigned long num, bytes;	Window *data = 0;	char *name;	Window rootWin = RootWindow(disp(), 0);	XGetWindowProperty(disp(), rootWin, active, 0L, ~0L, false,			   AnyPropertyType, &actualType, &format, &num, &bytes,			   (uint8_t **)&data);	int status = XFetchName(disp(), data[0], &name);	if (status >= Success && name != nullptr) {		std::string str(name);		title = str;	} else {		XTextProperty xtp_new_name;		if (XGetWMName(disp(), data[0], &xtp_new_name) != 0 &&		    xtp_new_name.value != nullptr) {			std::string str((const char *)xtp_new_name.value);			title = str;			XFree(xtp_new_name.value);		}	}	XFree(name);}
 |