wine_cloudmusic/disable_cloudmusic_shadows.cpp
2019-03-30 15:50:59 +08:00

202 lines
4.6 KiB
C++

/**
* https://www.cnblogs.com/Seiyagoo/p/3496945.html
* https://blog.csdn.net/ice__snow/article/details/79979298
* https://blog.csdn.net/lvbian/article/details/23031635
*
* This code is collected and generalized by hytzongxuan (hytzongxuan@gmail.com)
*/
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <sys/types.h>
#include <dirent.h>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <list>
#include <map>
#define BUF_SIZE 1024
using namespace std;
string PID[50];
int tot;
class WindowsMatchingPid
{
public:
WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid)
: _display(display), _pid(pid)
{
_atomPID = XInternAtom(display, "_NET_WM_PID", True);
if (_atomPID == None)
{
cout << "No such atom" << endl;
return;
}
search(wRoot);
}
const list<Window> &result() const { return _result; }
private:
unsigned long _pid;
Atom _atomPID;
Display *_display;
list<Window> _result;
void search(Window w)
{
Atom type;
int format;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char *propPID = 0;
if (Success == XGetWindowProperty(_display, w, _atomPID, 0, 1, False, XA_CARDINAL,
&type, &format, &nItems, &bytesAfter, &propPID))
{
if (propPID != 0)
{
if (_pid == *((unsigned long *)propPID))
_result.push_back(w);
XFree(propPID);
}
}
Window wRoot;
Window wParent;
Window *wChild;
unsigned nChildren;
if (0 != XQueryTree(_display, w, &wRoot, &wParent, &wChild, &nChildren))
{
for (unsigned i = 0; i < nChildren; i++)
search(wChild[i]);
}
}
};
void getPidByName(char *task_name)
{
DIR *dir;
struct dirent *ptr;
FILE *fp;
char filepath[50];
char cur_task_name[50];
char buf[BUF_SIZE];
dir = opendir("/proc");
if (NULL != dir)
{
while ((ptr = readdir(dir)) != NULL)
{
if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0))
continue;
if (DT_DIR != ptr->d_type)
continue;
sprintf(filepath, "/proc/%s/status", ptr->d_name);
fp = fopen(filepath, "r");
if (NULL != fp)
{
if (fgets(buf, BUF_SIZE - 1, fp) == NULL)
{
fclose(fp);
continue;
}
sscanf(buf, "%*s %s", cur_task_name);
if (!strcmp(task_name, cur_task_name))
{
PID[++tot] = ptr->d_name;
}
fclose(fp);
}
}
closedir(dir);
}
}
struct CloudMusicWindow
{
Window window;
int height, width;
CloudMusicWindow() {}
CloudMusicWindow(Window _win, int _h, int _w)
{
window = _win;
height = _h;
width = _w;
}
};
CloudMusicWindow cloudmusicwindow[50];
map<pair<int, int>, int> Map;
int window_cnt;
void findWindow(string x)
{
int pid = atoi(x.c_str());
Display *display = XOpenDisplay(0);
WindowsMatchingPid match(display, XDefaultRootWindow(display), pid);
const list<Window> &result = match.result();
for (list<Window>::const_iterator it = result.begin(); it != result.end(); it++)
{
XWindowAttributes attrs;
XGetWindowAttributes(display, (*it), &attrs);
Map[make_pair(attrs.height, attrs.width)]++;
cloudmusicwindow[++window_cnt] = CloudMusicWindow((*it), attrs.height, attrs.width);
}
}
int main(int argc, char **argv)
{
Display *display;
Window window;
XEvent event;
int s;
display = XOpenDisplay(NULL);
if (display == NULL)
{
fprintf(stderr, "Cannot open display\n");
exit(1);
}
getPidByName("cloudmusic.exe");
for (register int i = 1; i <= tot; i++)
{
findWindow(PID[i]);
}
s = DefaultScreen(display);
window = XCreateSimpleWindow(display, RootWindow(display, s), 10, 10, 1, 1, 1,
BlackPixel(display, s), WhitePixel(display, s));
XSelectInput(display, window, ExposureMask | KeyPressMask);
XMapWindow(display, window);
for (register int i = 1; i <= window_cnt; i++)
{
if (Map[make_pair(cloudmusicwindow[i].height, cloudmusicwindow[i].width)] == 2)
{
XReparentWindow(display, cloudmusicwindow[i].window, window, 1, 1);
}
}
XCloseDisplay(display);
return 0;
}