From cc178c807d2ced0e85b2aeecc3d969921ef7d377 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 14 Aug 2019 14:50:04 -0400 Subject: [PATCH] added logic to detect floating dialog windows --- TODO.md | 1 - src/anvil.c | 86 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/TODO.md b/TODO.md index f08af35..00a6e22 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ ## STAGING -* anvil: set default pointer style * anvil: support floating windows for dialogs * anvil: add column support * anvil: add support for multiple workspaces diff --git a/src/anvil.c b/src/anvil.c index 57ccc17..806f84f 100644 --- a/src/anvil.c +++ b/src/anvil.c @@ -16,6 +16,7 @@ enum { TOO_SMALL = (1 << 0), + FLOATING = (1 << 1), }; typedef struct Client { @@ -35,6 +36,7 @@ typedef struct Column { XConf X = {0}; Client* Clients = NULL; +Client* Floating = NULL; Cursor Move_Cursor; Cursor Main_Cursor; int StartY = 0; @@ -46,6 +48,11 @@ uint32_t BorderWidth = 1; 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) { @@ -62,6 +69,12 @@ void* xfree(void* p) { 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) { @@ -103,19 +116,49 @@ void client_raise(XConf* x, 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); @@ -129,17 +172,22 @@ void client_create(XConf* x, Window win) { 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); @@ -287,7 +335,7 @@ static void xconfigrequest(XConf* x, XEvent* e) { 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); } @@ -366,6 +414,10 @@ int main(void) { 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); -- 2.52.0