enum {
TOO_SMALL = (1 << 0),
+ FLOATING = (1 << 1),
};
typedef struct Client {
XConf X = {0};
Client* Clients = NULL;
+Client* Floating = NULL;
Cursor Move_Cursor;
Cursor Main_Cursor;
int StartY = 0;
uint32_t BorderColor = 0xFF0000;
uint32_t BackgroundColor = 0x000077;
+Atom
+ XA_NET_WM_WINDOW_TYPE,
+ XA_NET_WM_WINDOW_TYPE_DIALOG,
+ XA_WM_PROTOCOLS;
+
/* Utility Functions
*****************************************************************************/
void die(char* errstr) {
return NULL;
}
+int get_prop(XConf* x, Window w, Atom name, Atom* type, int* format, void** data, size_t* ndata) {
+ unsigned long nleft;
+ return XGetWindowProperty(
+ x->display, w, name, 0, -1, False, AnyPropertyType, type, format, ndata, &nleft, (unsigned char**)data);
+}
+
/* Client Handling
*****************************************************************************/
void client_add(Client* parent, Client* c) {
XMapRaised(x->display, c->win);
}
+void client_initprops(XConf* x, Client* c) {
+ int nprops = 0;
+ Atom* props = XListProperties(x->display, c->win, &nprops);
+ Atom type;
+ int format;
+ void* data = 0;
+ size_t ndata;
+ printf("props(%x) { \n", (int)c->win);
+ for (int i = 0; i < nprops; i++) {
+ printf(" %s\n", XGetAtomName(x->display, props[i]));
+ if (props[i] == XA_NET_WM_WINDOW_TYPE) {
+ if (Success == get_prop(x, c->win, props[i], &type, &format, &data, &ndata))
+ if (((Atom*)data)[0] == XA_NET_WM_WINDOW_TYPE_DIALOG)
+ c->flags |= FLOATING;
+ } else if (props[i] == XA_WM_PROTOCOLS) {
+
+ }
+ data = xfree(data);
+ }
+ printf("}\n");
+}
+
void client_create(XConf* x, Window win) {
Client* c = calloc(1, sizeof(Client));
c->win = win;
XGrabServer(x->display);
XFetchName(x->display, win, &c->name);
+ client_initprops(x, c);
/* create the frame window */
- XWindowAttributes attr;
- XGetWindowAttributes(x->display, win, &attr);
- c->x = 0, c->y = 0;
- c->w = WidthOfScreen(DefaultScreenOfDisplay(x->display));
- c->h = HeightOfScreen(DefaultScreenOfDisplay(x->display));
- c->frame = XCreateSimpleWindow(x->display, x->root, 0, 0, 1, 1, BorderWidth, BorderColor, BackgroundColor);
+ if (c->flags & FLOATING) {
+ XWindowAttributes attr;
+ XGetWindowAttributes(x->display, win, &attr);
+ c->x = attr.x, c->y = attr.y;
+ c->w = attr.width;
+ c->h = attr.height;
+ } else {
+ c->x = 0, c->y = 0;
+ c->w = WidthOfScreen(DefaultScreenOfDisplay(x->display));
+ c->h = HeightOfScreen(DefaultScreenOfDisplay(x->display));
+ }
+
+ c->frame = XCreateSimpleWindow(x->display, x->root, c->x, c->y, 1, 1, BorderWidth, BorderColor, BackgroundColor);
c->xft = XftDrawCreate(x->display, (Drawable) c->frame, x->visual, x->colormap);
XSetWindowAttributes pattr = { .override_redirect = True };
XChangeWindowAttributes(x->display, c->frame, CWOverrideRedirect, &pattr);
EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
/* position the window and frame */
- Client* biggy = Clients;
- for (Client* curr = Clients; curr; curr = curr->next)
- if (curr->h > biggy->h) biggy = curr;
- if (biggy) {
- c->h = (biggy->h - (biggy->h / 2));
- biggy->h /= 2;
- c->y = biggy->y + biggy->h;
- client_config(x, biggy, biggy->x, biggy->y, biggy->w, biggy->h);
- client_add(biggy, c);
+ if (!(c->flags & FLOATING)) {
+ Client* biggy = Clients;
+ for (Client* curr = Clients; curr; curr = curr->next)
+ if (curr->h > biggy->h) biggy = curr;
+ if (biggy) {
+ c->h = (biggy->h - (biggy->h / 2));
+ biggy->h /= 2;
+ c->y = biggy->y + biggy->h;
+ client_config(x, biggy, biggy->x, biggy->y, biggy->w, biggy->h);
+ client_add(biggy, c);
+ } else {
+ Clients = c;
+ }
} else {
- Clients = c;
+// client_add(c, Floating);
+// Floating = c;
}
client_config(x, c, c->x, c->y, c->w, c->h);
client_raise(x, c);
wc.border_width = e->xconfigurerequest.border_width;
wc.sibling = e->xconfigurerequest.above;
wc.stack_mode = e->xconfigurerequest.detail;
- if (c /* && !(c->flags & FLOATING) */)
+ if (c && !(c->flags & FLOATING))
return;
XConfigureWindow(x->display, e->xconfigurerequest.window, e->xconfigurerequest.value_mask, &wc);
}
if (x11_error_get())
die("Could not start. Is another WM running?\n");
+ XA_NET_WM_WINDOW_TYPE = atom(&X, "_NET_WM_WINDOW_TYPE");
+ XA_NET_WM_WINDOW_TYPE_DIALOG = atom(&X, "_NET_WM_WINDOW_TYPE_DIALOG");
+ XA_WM_PROTOCOLS = atom(&X, "WM_PROTOCOLS");
+
/* setup cursors */
Main_Cursor = XCreateFontCursor(X.display, XC_left_ptr);
Move_Cursor = XCreateFontCursor(X.display, XC_draped_box);