Code submissions have continually suffered from formatting inconsistencies that constantly have to be addressed. Using clang-format simplifies this by making code formatting more consistent, and allows automation of the code formatting so that maintainers can focus more on the code itself instead of code formatting.
174 lines
3.2 KiB
C++
174 lines
3.2 KiB
C++
#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 cleanupDisplay()
|
|
{
|
|
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);
|
|
|
|
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;
|
|
}
|
|
|
|
XFree(name);
|
|
}
|