#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "WinMgr.h" #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #define KEY_MODMASK(x) ((x) & (ControlMask | ShiftMask | Mod1Mask)) static char *displayName = 0; static Display *display = 0; static Colormap defaultColormap; static Window root = None; static Window window = None; ///static GC gc; static long workspaceCount = 4; static long activeWorkspace = 0; static long windowWorkspace = 0; static long state[2] = { 0, 0 }; ///static bool sticky = false; static Atom _XA_WIN_WORKSPACE; static Atom _XA_WIN_WORKSPACE_NAMES; static Atom _XA_WIN_STATE; static Atom _XA_WIN_LAYER; static Atom _XA_WIN_WORKAREA; static Atom _XA_WIN_TRAY; static Atom _XA_NET_WM_MOVERESIZE; void changeWorkspace(Window w, long workspace) { XClientMessageEvent xev; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.window = w; xev.message_type = _XA_WIN_WORKSPACE; xev.format = 32; xev.data.l[0] = workspace; xev.data.l[1] = CurrentTime; //xev.data.l[1] = timeStamp; XSendEvent(display, root, False, SubstructureNotifyMask, (XEvent *) &xev); } void moveResize(Window w, int x, int y, int what) { XClientMessageEvent xev; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.window = w; xev.message_type = _XA_NET_WM_MOVERESIZE; xev.format = 32; xev.data.l[0] = x; xev.data.l[1] = y; //xev.data.l[1] = timeStamp; xev.data.l[2] = what; XSendEvent(display, root, False, SubstructureNotifyMask, (XEvent *) &xev); } void toggleState(Window w, long new_state) { XClientMessageEvent xev; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.window = w; xev.message_type = _XA_WIN_STATE; xev.data.l[0] = (state[0] & state[1] & new_state) ^ new_state; xev.data.l[1] = new_state; xev.data.l[2] = CurrentTime; //xev.data.l[1] = timeStamp; XSendEvent(display, root, False, SubstructureNotifyMask, (XEvent *) &xev); } void setLayer(Window w, long layer) { XClientMessageEvent xev; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.window = w; xev.message_type = _XA_WIN_LAYER; xev.format = 32; xev.data.l[0] = layer; xev.data.l[1] = CurrentTime; //xev.data.l[1] = timeStamp; XSendEvent(display, root, False, SubstructureNotifyMask, (XEvent *) &xev); } void setTrayHint(Window w, long tray_opt) { XClientMessageEvent xev; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.window = w; xev.message_type = _XA_WIN_TRAY; xev.format = 32; xev.data.l[0] = tray_opt; xev.data.l[1] = CurrentTime; //xev.data.l[1] = timeStamp; XSendEvent(display, root, False, SubstructureNotifyMask, (XEvent *) &xev); } int main(/*int argc, char **argv*/) { XSetWindowAttributes attr; assert((display = XOpenDisplay(displayName)) != 0); root = RootWindow(display, DefaultScreen(display)); defaultColormap = DefaultColormap(display, DefaultScreen(display)); _XA_WIN_WORKSPACE = XInternAtom(display, XA_WIN_WORKSPACE, False); _XA_WIN_WORKSPACE_NAMES = XInternAtom(display, XA_WIN_WORKSPACE_NAMES, False); _XA_WIN_STATE = XInternAtom(display, XA_WIN_STATE, False); _XA_WIN_LAYER = XInternAtom(display, XA_WIN_LAYER, False); _XA_WIN_WORKAREA = XInternAtom(display, XA_WIN_WORKAREA, False); _XA_WIN_TRAY = XInternAtom(display, XA_WIN_TRAY, False); _XA_NET_WM_MOVERESIZE = XInternAtom(display, "_NET_WM_MOVERESIZE", False); window = XCreateWindow(display, root, 0, 0, 64, 64, 0, CopyFromParent, InputOutput, CopyFromParent, 0, &attr); XSetWindowBackground(display, window, BlackPixel(display, DefaultScreen(display))); XSelectInput(display, window, ExposureMask | StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask); XSelectInput(display, root, PropertyChangeMask); XMapRaised(display, window); while (1) { XEvent xev; /// XButtonEvent &button = xev.xbutton; XPropertyEvent &property = xev.xproperty; XKeyEvent &key = xev.xkey; XNextEvent(display, &xev); switch (xev.type) { case KeyPress: { unsigned int k = XKeycodeToKeysym(display, key.keycode, 0); unsigned int m = KEY_MODMASK(key.state); if (k == XK_Left && m == 0) changeWorkspace(root, (workspaceCount + activeWorkspace - 1) % workspaceCount); else if (k == XK_Right && m == 0) changeWorkspace(root, (activeWorkspace + 1) % workspaceCount); else if (k == XK_Left && m == ShiftMask) changeWorkspace(window, (workspaceCount + windowWorkspace - 1) % workspaceCount); else if (k == XK_Right && m == ShiftMask) changeWorkspace(window, (windowWorkspace + 1) % workspaceCount); else if (k == 's') toggleState(window, WinStateSticky); /* else if (k == 'd') toggleState(window, WinStateDockHorizontal); */ else if (k == '0') setLayer(window, WinLayerDesktop); else if (k == '1') setLayer(window, WinLayerBelow); else if (k == '2') setLayer(window, WinLayerNormal); else if (k == '3') setLayer(window, WinLayerOnTop); else if (k == '4') setLayer(window, WinLayerDock); else if (k == '5') setLayer(window, WinLayerAboveDock); else if (k == 'm') { printf("%d %d\n", key.x_root, key.y_root); moveResize(window, key.x_root, key.y_root, 8); // move } else if (k == 'r') { printf("%d %d\n", key.x_root, key.y_root); moveResize(window, key.x_root, key.y_root, 4); // _| } } break; case PropertyNotify: { Atom r_type; int r_format; unsigned long count; unsigned long bytes_remain; unsigned char *prop(0); if (property.window == root) { if (property.atom == _XA_WIN_WORKSPACE) { if (XGetWindowProperty(display, root, _XA_WIN_WORKSPACE, 0, 1, False, XA_CARDINAL, &r_type, &r_format, &count, &bytes_remain, &prop) == Success && prop) { if (r_type == XA_CARDINAL && r_format == 32 && count == 1) { activeWorkspace = ((long *)prop)[0]; printf("active=%ld of %ld\n", activeWorkspace, workspaceCount); } XFree(prop); } } else if (property.atom == _XA_WIN_WORKSPACE_NAMES) { } else if (property.atom == _XA_WIN_WORKAREA) { if (XGetWindowProperty(display, root, _XA_WIN_WORKAREA, 0, 4, False, XA_CARDINAL, &r_type, &r_format, &count, &bytes_remain, &prop) == Success && prop) { if (r_type == XA_CARDINAL && r_format == 32 && count == 4) { long *area = (long *)prop; printf("workarea: min=%ld,%ld max=%ld,%ld\n", area[0], area[1], area[2], area[3]); } XFree(prop); } } } else if (property.window == window) { if (property.atom == _XA_WIN_WORKSPACE) { if (XGetWindowProperty(display, window, _XA_WIN_WORKSPACE, 0, 1, False, XA_CARDINAL, &r_type, &r_format, &count, &bytes_remain, &prop) == Success && prop) { if (r_type == XA_CARDINAL && r_format == 32 && count == 1) { windowWorkspace = ((long *)prop)[0]; printf("window=%ld of %ld\n", windowWorkspace, workspaceCount); } XFree(prop); } } else if (property.atom == _XA_WIN_STATE) { if (XGetWindowProperty(display, window, _XA_WIN_STATE, 0, 2, False, XA_CARDINAL, &r_type, &r_format, &count, &bytes_remain, &prop) == Success && prop) { if (r_type == XA_CARDINAL && r_format == 32 && count == 2) { state[0] = ((long *)prop)[0]; state[1] = ((long *)prop)[1]; printf("state=%lX %lX\n", state[0], state[1]); } XFree(prop); } } else if (property.atom == _XA_WIN_LAYER) { if (XGetWindowProperty(display, window, _XA_WIN_LAYER, 0, 1, False, XA_CARDINAL, &r_type, &r_format, &count, &bytes_remain, &prop) == Success && prop) { if (r_type == XA_CARDINAL && r_format == 32 && count == 1) { long layer = ((long *)prop)[0]; printf("layer=%ld\n", layer); } XFree(prop); } } else if (property.atom == _XA_WIN_TRAY) { if (XGetWindowProperty(display, window, _XA_WIN_TRAY, 0, 1, False, XA_CARDINAL, &r_type, &r_format, &count, &bytes_remain, &prop) == Success && prop) { if (r_type == XA_CARDINAL && r_format == 32 && count == 1) { long tray = ((long *)prop)[0]; printf("tray option=%ld\n", tray); } } } } } } } } // vim: set sw=4 ts=4 et: