/** Determine if this is a window to be swallowed, if it is, swallow it. */ int CheckSwallowMap(const XMapEvent *event) { SwallowNode *np; XClassHint hint; XWindowAttributes attr; for(np = swallowNodes; np; np = np->next) { if(np->cp->window != None) { continue; } Assert(np->cp->tray->window != None); if(JXGetClassHint(display, event->window, &hint)) { if(!strcmp(hint.res_name, np->name)) { /* Swallow the window. */ JXSelectInput(display, event->window, StructureNotifyMask | ResizeRedirectMask); JXAddToSaveSet(display, event->window); JXSetWindowBorder(display, event->window, colors[COLOR_TRAY_BG]); JXReparentWindow(display, event->window, np->cp->tray->window, 0, 0); JXMapRaised(display, event->window); JXFree(hint.res_name); JXFree(hint.res_class); np->cp->window = event->window; /* Update the size. */ JXGetWindowAttributes(display, event->window, &attr); np->border = attr.border_width; if(!np->userWidth) { np->cp->requestedWidth = attr.width + 2 * np->border; } if(!np->userHeight) { np->cp->requestedHeight = attr.height + 2 * np->border; } ResizeTray(np->cp->tray); return 1; } else { JXFree(hint.res_name); JXFree(hint.res_class); } } } return 0; }
/** Add a window to the dock. */ void DockWindow(Window win) { DockNode *np; /* If no dock is running, just return. */ if(!dock) { return; } /* Make sure we have a valid window to add. */ if(JUNLIKELY(win == None)) { return; } /* If this window is already docked ignore it. */ for(np = dock->nodes; np; np = np->next) { if(np->window == win) { return; } } /* Add the window to our list. */ np = Allocate(sizeof(DockNode)); np->window = win; np->needs_reparent = 0; np->next = dock->nodes; dock->nodes = np; /* Update the requested size. */ GetDockSize(&dock->cp->requestedWidth, &dock->cp->requestedHeight); /* It's safe to reparent at (0, 0) since we call * ResizeTray which will invoke the Resize callback. */ JXAddToSaveSet(display, win); JXReparentWindow(display, win, dock->cp->window, 0, 0); JXMapRaised(display, win); /* Resize the tray containing the dock. */ ResizeTray(dock->cp->tray); }
/** Reparent a client window. */ void ReparentClient(ClientNode *np, char notOwner) { XSetWindowAttributes attr; int attrMask; int x, y, width, height; int north, south, east, west; Assert(np); if(notOwner) { JXAddToSaveSet(display, np->window); attr.event_mask = EnterWindowMask | ColormapChangeMask | PropertyChangeMask | KeyReleaseMask | StructureNotifyMask; attr.do_not_propagate_mask = NoEventMask; JXChangeWindowAttributes(display, np->window, CWEventMask | CWDontPropagate, &attr); } JXGrabButton(display, AnyButton, AnyModifier, np->window, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); if((np->state.border & (BORDER_TITLE | BORDER_OUTLINE)) == 0) { return; } attrMask = 0; /* We can't use PointerMotionHint mask here since the exact location * of the mouse on the frame is important. */ attrMask |= CWEventMask; attr.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask | SubstructureRedirectMask | SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask; attrMask |= CWDontPropagate; attr.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask; attrMask |= CWBackPixel; attr.background_pixel = colors[COLOR_TITLE_BG2]; attrMask |= CWBorderPixel; attr.border_pixel = 0; x = np->x; y = np->y; width = np->width; height = np->height; GetBorderSize(&np->state, &north, &south, &east, &west); x -= west; y -= north; width += east + west; height += north + south; /* Create the frame window. */ np->parent = JXCreateWindow(display, rootWindow, x, y, width, height, 0, rootDepth, InputOutput, rootVisual, attrMask, &attr); /* Update the window to get only the events we want. */ attrMask = CWDontPropagate; attr.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask; /* Make sure client doesn't muck with these. */ attrMask |= CWBackingStore; attr.backing_store = NotUseful; attrMask |= CWWinGravity; attr.win_gravity = NorthWestGravity; JXChangeWindowAttributes(display, np->window, attrMask, &attr); JXSetWindowBorderWidth(display, np->window, 0); /* Reparent the client window. */ JXReparentWindow(display, np->window, np->parent, west, north); }