static void check_for_wm(void)
{
error_default = XSetErrorHandler(error_init);
- XSelectInput(X.disp, X.root, SubstructureRedirectMask);
+ XSelectInput(X.disp, X.root, SubstructureRedirectMask|SubstructureNotifyMask);
XSync(X.disp, False);
XSetErrorHandler(error_panic);
XSync(X.disp, False);
wc.border_width = ev->border_width;
wc.sibling = ev->above;
wc.stack_mode = ev->detail;
- Location loc = {0};
- if (mons_find(ev->window, &loc))
- {
- /* only allow floating clients to resize on their own */
- if ((loc.client->win == ev->window) && !loc.column)
- {
- loc.client->w = wc.width + FRAME_WIDTH_SUM;
- loc.client->h = wc.height + FRAME_HEIGHT_SUM;
- client_adjust(loc.client);
- if (X.mode == M_RESIZE && Focused == loc.client)
- {
- mouse_tocorner(loc.client);
- }
- }
- }
- else
+// Location loc = {0};
+// if (mons_find(ev->window, &loc))
+// {
+// /* only allow floating clients to resize on their own */
+// if ((loc.client->win == ev->window) && !loc.column)
+// {
+// loc.client->w = wc.width + FRAME_WIDTH_SUM;
+// loc.client->h = wc.height + FRAME_HEIGHT_SUM;
+// client_adjust(loc.client);
+// if (X.mode == M_RESIZE && Focused == loc.client)
+// {
+// mouse_tocorner(loc.client);
+// }
+// }
+// }
+// else
{
XConfigureWindow(X.disp, ev->window, ev->value_mask, &wc);
}
printf("CLIENT_MSG(w: 0x%lx a: '%s')\n", ev->window, XGetAtomName(X.disp, ev->message_type));
if (ev->message_type == _NET_ACTIVE_WINDOW)
{
- mons_activate(ev->window);
+// mons_activate(ev->window);
}
}
{
XPropertyEvent* ev = &(e->xproperty);
printf("PROP_NOTIFY(w: 0x%lx)\n", ev->window);
- Location loc = {0};
- if (mons_find(ev->window, &loc))
- {
- client_readprops(loc.client);
- client_draw(loc.client);
- }
+// Location loc = {0};
+// if (mons_find(ev->window, &loc))
+// {
+// client_readprops(loc.client);
+// client_draw(loc.client);
+// }
}
static void xenternotify(XEvent* e)
{
XCrossingEvent* ev = &(e->xcrossing);
- Location loc = {0};
+// Location loc = {0};
printf("ENTER(w: 0x%lx s: %d m: %d d: %d)\n", ev->window, ev->state, ev->mode, ev->detail);
- if (mons_find(ev->window, &loc))
- {
- client_focus(loc.client);
- }
+// if (mons_find(ev->window, &loc))
+// {
+// client_focus(loc.client);
+// }
}
static void xexpose(XEvent* e)
if (ev->count == 0)
{
printf("EXPOSE(w: 0x%lx)\n", ev->window);
- Location loc = {0};
- if (mons_find(ev->window, &loc))
- {
- client_draw(loc.client);
- }
+// Location loc = {0};
+// if (mons_find(ev->window, &loc))
+// {
+// client_draw(loc.client);
+// }
}
}
{
XMapEvent* ev = &(e->xmap);
printf("MAP(e: 0x%lx w: 0x%lx)\n", ev->event, ev->window);
- Location loc = {0};
- if (mons_find(ev->window, &loc))// && loc.client->win == ev->window)
- {
- client_draw(loc.client);
- }
+// Location loc = {0};
+// if (mons_find(ev->window, &loc))// && loc.client->win == ev->window)
+// {
+// client_draw(loc.client);
+// }
}
#include "anvil.h"
+static Client* FindClient(Window win);
+static void ReadProps(Client* c);
+static void Redraw(Client* c);
+
+void SetWMState(Client *c, int state)
+{
+ CARD32 data[2] = {state, None};
+ XChangeProperty(X.disp, c->win, WM_STATE, WM_STATE, 32, PropModeReplace, (unsigned char *)data, 2);
+}
+
+///* If we can't find a WM_STATE we're going to have to assume
+// * Withdrawn. This is not exactly optimal, since we can't really
+// * distinguish between the case where no WM has run yet and when the
+// * state was explicitly removed (Clients are allowed to either set the
+// * atom to Withdrawn or just remove it... yuck.) */
+//
+//long GetWMState(Client *c)
+//{
+// Atom real_type;
+// int real_format;
+// long state = WithdrawnState;
+// unsigned long items_read, items_left;
+// unsigned char *data;
+//
+// if (XGetWindowProperty(dsply, c->window, wm_state, 0L, 2L, False, wm_state, &real_type, &real_format, &items_read, &items_left, &data) == Success && items_read)
+// {
+// state = *(long *)data;
+// XFree(data);
+// }
+// return state;
+//}
+
void Client_Create(Window win)
{
(void)win;
/* Reparent the window if applicable */
c->frame = XCreateSimpleWindow(X.disp, X.root, c->x, c->y, c->w, c->h, 1, X.clr_bdr, X.clr_bg);
+ XAddToSaveSet(X.disp, c->win);
XSelectInput(X.disp, c->frame,
ExposureMask | EnterWindowMask |
ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
wa.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask;
XChangeWindowAttributes(X.disp, c->win, CWEventMask | CWDontPropagate, &wa);
XReparentWindow(X.disp, c->win, c->frame, BORDER_WIDTH, MIN_HEIGHT);
+ SetWMState(c, WithdrawnState);
-// /* Map the window and draw the frame */
-// XAddToSaveSet(X.disp, c->win);
-// client_readprops(c);
-// mons_addclient(c);
-// client_show(c, 1);
-// client_draw(c);
+// /* set the state now based on attributes and hints */
+// if (attr.map_state == IsUnmapped)
+// {
+// SetWMState(c, WithdrawnState);
+// }
+// else
+// {
+// SetWMState(c, NormalState);
+// XWMHints* hints = XGetWMHints(X.disp, c->win);
+// if (hints)
+// {
+// if (hints->flags & StateHint)
+// {
+// SetWMState(c, hints->initial_state);
+// }
+// XFree(hints);
+// }
+// }
}
}
void Client_Show(Window win)
{
- (void)win;
+ Client* c = FindClient(win);
+ printf("%p %p\n", Withdrawn, c);
+ if (c)
+ {
+ ReadProps(c);
+ XMapWindow(X.disp, c->frame);
+ XMapWindow(X.disp, c->win);
+ Redraw(c);
+ }
}
void Client_Hide(Window win)
}
+static void ReadProps(Client* c)
+{
+ Atom *protos = NULL, actual_type, *wintype;
+ int format, nprotos = 0;
+ unsigned long n, extra;
+
+ /* WM_NAME - window title */
+ xfree(c->name);
+ c->name = NULL;
+ XGetWindowProperty(
+ X.disp, c->win, XA_WM_NAME, 0, -1, False, AnyPropertyType, &actual_type, &format, &n, &extra, (unsigned char **)&c->name);
+
+ /* WM_HINTS - other non-dimensional attributes of the window */
+ XWMHints* hints = XGetWMHints(X.disp, c->win);
+ if (hints)
+ {
+ int ignored = (Focused == c ? XUrgencyHint : 0);
+ c->wm_flags = (hints->flags & ~ignored);
+ c->hints = *hints;
+ }
+ xfree(hints);
+
+ /* WM_NORMAL_HINTS - desired dimensional attributes of the window */
+ XGetWMNormalHints(X.disp, c->win, &(c->size_hints), &(c->hint_flags));
+
+ /* WM_PROTOCOLS - list of client message protocols this window responds to */
+ XGetWMProtocols(X.disp, c->win, &protos, &nprotos);
+ for (int i = 0; i < nprotos; i++)
+ {
+ if (protos[i] == WM_DELETE_WINDOW)
+ {
+ c->flags |= F_WM_DELETE;
+ }
+
+ // TODO: handle WM_TAKE_FOCUS
+ }
+ xfree(protos);
+
+ /* WM_CLASS - instance and class names of the window. informs WM about behavior of window */
+ // TODO: Read the class and instance of the window
+
+ /* WM_TRANSIENT_FOR - marks the window as a pop-up for another window */
+ // TODO: read the transient_for property and use ti to handle pop-ups better
+
+ /* WM_CLIENT_MACHINE - */
+ // TODO: read client machine property
+
+ /* check if the window is a dialog */
+ XGetWindowProperty(
+ X.disp, c->win, _NET_WM_WINDOW_TYPE, 0L, -1, False, XA_ATOM, &actual_type, &format, &n, &extra, (unsigned char **)&wintype);
+ if (wintype && *wintype == _NET_WM_WINDOW_TYPE_DIALOG)
+ {
+ c->flags |= F_DIALOG|F_FLOATING;
+ }
+ xfree(wintype);
+
+ /* The following properties are unused currently */
+ /* WM_ICON_NAME - window title when iconified */
+ /* WM_COLORMAP_WINDOWS - */
+}
+
+static void Redraw(Client* c)
+{
+ if (c->frame)
+ {
+ XSetWindowBackground(X.disp, c->frame, ((c->wm_flags & XUrgencyHint) ? X.clr_urgent : X.clr_bg));
+ XSetWindowBorderWidth(X.disp, c->frame, 0);
+ XSetWindowBorderWidth(X.disp, c->win, 0);
+ XDefineCursor(X.disp, c->frame, X.csr_point);
+ XClearWindow(X.disp, c->frame);
+
+ /* set border color */
+ XSetForeground(X.disp, DefaultGC(X.disp, X.screen), BlackPixel(X.disp, X.screen));
+ XSetFillStyle(X.disp, DefaultGC(X.disp, X.screen), FillSolid);
+
+ /* draw outer border */
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), 0, 0, c->w, 0);
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), 0, c->h-1, c->w, c->h-1);
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), 0, 0, 0, c->h);
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), c->w-1, 0, c->w-1, c->h);
+
+ /* draw inner border */
+ if (!(c->flags & F_SHADED))
+ {
+ int bw = BORDER_WIDTH;
+ int mh = MIN_HEIGHT;
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
+ bw-1, mh-1, c->w-bw, mh-1);
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
+ bw-1, c->h-bw, c->w-bw, c->h-bw);
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
+ bw-1, mh-1, bw-1, c->h-bw);
+ XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
+ c->w-bw, mh-1, c->w-bw, c->h-bw);
+ }
+
+ /* draw title text */
+ if (c->name) {
+ int ascent = abs(X.font_ext->max_logical_extent.y);
+ Xutf8DrawString(X.disp, c->frame, X.font,
+ DefaultGC(X.disp, X.screen),
+ BORDER_WIDTH,
+ 2 + ascent,
+ c->name, strlen(c->name));
+ }
+ }
+
+ /* tell the window to redraw itself */
+// XClearArea(X.disp, c->win, 0, 0, 0, 0, True);
+}
+
+static Client* FindClient(Window win)
+{
+ Client* curr = Withdrawn;
+ for (; curr; curr = curr->next)
+ {
+ if (curr->win == win || curr->frame == win)
+ {
+ break;
+ }
+ }
+ return curr;
+}
+
c->y = attr->y;
c->w = attr->width + FRAME_WIDTH_SUM;
c->h = attr->height + FRAME_HEIGHT_SUM;
- client_readprops(c);
+ ReadProps(c);
/* Reparent the window if applicable */
c->frame = XCreateSimpleWindow(X.disp, X.root, c->x, c->y, c->w, c->h, 1, X.clr_bdr, X.clr_bg);
XAddToSaveSet(X.disp, c->win);
mons_addclient(c);
client_show(c, 1);
- client_draw(c);
+ Redraw(c);
return c;
}
-void client_draw(Client* c)
-{
- if (c->frame)
- {
- XSetWindowBackground(X.disp, c->frame, ((c->wm_flags & XUrgencyHint) ? X.clr_urgent : X.clr_bg));
- XSetWindowBorderWidth(X.disp, c->frame, 0);
- XSetWindowBorderWidth(X.disp, c->win, 0);
- XDefineCursor(X.disp, c->frame, X.csr_point);
- XClearWindow(X.disp, c->frame);
-
- /* set border color */
- XSetForeground(X.disp, DefaultGC(X.disp, X.screen), BlackPixel(X.disp, X.screen));
- XSetFillStyle(X.disp, DefaultGC(X.disp, X.screen), FillSolid);
-
- /* draw outer border */
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), 0, 0, c->w, 0);
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), 0, c->h-1, c->w, c->h-1);
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), 0, 0, 0, c->h);
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen), c->w-1, 0, c->w-1, c->h);
-
- /* draw inner border */
- if (!(c->flags & F_SHADED))
- {
- int bw = BORDER_WIDTH;
- int mh = MIN_HEIGHT;
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
- bw-1, mh-1, c->w-bw, mh-1);
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
- bw-1, c->h-bw, c->w-bw, c->h-bw);
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
- bw-1, mh-1, bw-1, c->h-bw);
- XDrawLine(X.disp, c->frame, DefaultGC(X.disp, X.screen),
- c->w-bw, mh-1, c->w-bw, c->h-bw);
- }
-
- /* draw title text */
- if (c->name) {
- int ascent = abs(X.font_ext->max_logical_extent.y);
- Xutf8DrawString(X.disp, c->frame, X.font,
- DefaultGC(X.disp, X.screen),
- BORDER_WIDTH,
- 2 + ascent,
- c->name, strlen(c->name));
- }
- }
-
- /* tell the window to redraw itself */
-// XClearArea(X.disp, c->win, 0, 0, 0, 0, True);
-}
void client_adjust(Client* c)
{
XResizeWindow(X.disp, c->win, child_w, child_h);
}
mons_place(c);
-// client_draw(c);
+// Redraw(c);
}
void client_move(Client* c, int xdiff, int ydiff)
Client* prev = Focused;
Focused = c;
XSetInputFocus(X.disp, c->win, RevertToPointerRoot, CurrentTime);
- client_draw(Focused);
+ Redraw(Focused);
if (prev)
{
- client_draw(prev);
+ Redraw(prev);
}
}
mapfn(X.disp, c->win);
}
-void client_readprops(Client* c)
-{
- Atom *protos = NULL, actual_type, *wintype;
- int format, nprotos = 0;
- unsigned long n, extra;
-
- /* WM_NAME - window title */
- xfree(c->name);
- c->name = NULL;
- XGetWindowProperty(
- X.disp, c->win, XA_WM_NAME, 0, -1, False, AnyPropertyType, &actual_type, &format, &n, &extra, (unsigned char **)&c->name);
-
- /* WM_HINTS - other non-dimensional attributes of the window */
- XWMHints* hints = XGetWMHints(X.disp, c->win);
- if (hints)
- {
- int ignored = (Focused == c ? XUrgencyHint : 0);
- c->wm_flags = (hints->flags & ~ignored);
- c->hints = *hints;
- }
- xfree(hints);
-
- /* WM_NORMAL_HINTS - desired dimensional attributes of the window */
- XGetWMNormalHints(X.disp, c->win, &(c->size_hints), &(c->hint_flags));
-
- /* WM_PROTOCOLS - list of client message protocols this window responds to */
- XGetWMProtocols(X.disp, c->win, &protos, &nprotos);
- for (int i = 0; i < nprotos; i++)
- {
- if (protos[i] == WM_DELETE_WINDOW)
- {
- c->flags |= F_WM_DELETE;
- }
-
- // TODO: handle WM_TAKE_FOCUS
- }
- xfree(protos);
-
- /* WM_CLASS - instance and class names of the window. informs WM about behavior of window */
- // TODO: Read the class and instance of the window
-
- /* WM_TRANSIENT_FOR - marks the window as a pop-up for another window */
- // TODO: read the transient_for property and use ti to handle pop-ups better
-
- /* WM_CLIENT_MACHINE - */
- // TODO: read client machine property
-
- /* check if the window is a dialog */
- XGetWindowProperty(
- X.disp, c->win, _NET_WM_WINDOW_TYPE, 0L, -1, False, XA_ATOM, &actual_type, &format, &n, &extra, (unsigned char **)&wintype);
- if (wintype && *wintype == _NET_WM_WINDOW_TYPE_DIALOG)
- {
- c->flags |= F_DIALOG|F_FLOATING;
- }
- xfree(wintype);
-
- /* The following properties are unused currently */
- /* WM_ICON_NAME - window title when iconified */
- /* WM_COLORMAP_WINDOWS - */
-}
void client_shade(Client* c)
{