/** Show a confirm dialog. */ void ShowConfirmDialog(ClientNode *np, void (*action)(ClientNode*), ...) { va_list ap; XSetWindowAttributes attrs; XSizeHints shints; Window window; char *str; int x; Assert(action); /* Only allow one dialog at a time. */ if(dialog) { DestroyConfirmDialog(); } dialog = Allocate(sizeof(DialogType)); dialog->client = np ? np->window : None; dialog->action = action; dialog->buttonState = DBS_NORMAL; /* Get the number of lines. */ va_start(ap, action); for(dialog->lineCount = 0; va_arg(ap, char*); dialog->lineCount++); va_end(ap); dialog->message = Allocate(dialog->lineCount * sizeof(char*)); va_start(ap, action); for(x = 0; x < dialog->lineCount; x++) { str = va_arg(ap, char*); dialog->message[x] = CopyString(str); } va_end(ap); ComputeDimensions(np); /* Create the pixmap used for rendering. */ dialog->pmap = JXCreatePixmap(display, rootWindow, dialog->width, dialog->height, rootDepth); /* Create the window. */ attrs.background_pixel = colors[COLOR_MENU_BG]; attrs.event_mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask | ExposureMask; window = JXCreateWindow(display, rootWindow, dialog->x, dialog->y, dialog->width, dialog->height, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWEventMask, &attrs); shints.x = dialog->x; shints.y = dialog->y; shints.flags = PPosition; JXSetWMNormalHints(display, window, &shints); JXStoreName(display, window, _("Confirm")); SetAtomAtom(window, ATOM_NET_WM_WINDOW_TYPE, ATOM_NET_WM_WINDOW_TYPE_DIALOG); /* Draw the dialog. */ DrawDialog(); /* Add the client and give it focus. */ dialog->node = AddClientWindow(window, 0, 0); Assert(dialog->node); if(np) { dialog->node->owner = np->window; } dialog->node->state.status |= STAT_WMDIALOG; FocusClient(dialog->node); /* Grab the mouse. */ JXGrabButton(display, AnyButton, AnyModifier, window, True, ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); }
/** Show a confirm dialog. */ void ShowConfirmDialog(ClientNode *np, void (*action)(ClientNode*), ...) { va_list ap; DialogType *dp; XSetWindowAttributes attrs; XSizeHints shints; Window window; char *str; int x; Assert(action); dp = Allocate(sizeof(DialogType)); dp->client = np; dp->action = action; dp->buttonState = DBS_NORMAL; dp->prev = NULL; dp->next = dialogList; if(dialogList) { dialogList->prev = dp; } dialogList = dp; /* Get the number of lines. */ va_start(ap, action); for(dp->lineCount = 0; va_arg(ap, char*); dp->lineCount++); va_end(ap); dp->message = Allocate(dp->lineCount * sizeof(char*)); va_start(ap, action); for(x = 0; x < dp->lineCount; x++) { str = va_arg(ap, char*); dp->message[x] = CopyString(str); } va_end(ap); ComputeDimensions(dp); attrs.background_pixel = colors[COLOR_TRAY_BG]; attrs.event_mask = ButtonReleaseMask | ExposureMask; window = JXCreateWindow(display, rootWindow, dp->x, dp->y, dp->width, dp->height, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWEventMask, &attrs); shints.x = dp->x; shints.y = dp->y; shints.flags = PPosition; JXSetWMNormalHints(display, window, &shints); JXStoreName(display, window, "Confirm"); dp->node = AddClientWindow(window, 0, 0); Assert(dp->node); if(np) { dp->node->owner = np->window; } dp->node->state.status |= STAT_WMDIALOG; FocusClient(dp->node); DrawConfirmDialog(dp); JXGrabButton(display, AnyButton, AnyModifier, window, True, ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); }
/** 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); }