/** Handle a map request. */ void HandleMapRequest(const XMapEvent *event) { ClientNode *np; Assert(event); if(CheckSwallowMap(event)) { return; } np = FindClientByWindow(event->window); if(!np) { JXSync(display, False); JXGrabServer(display); np = AddClientWindow(event->window, 0, 1); if(np) { if(focusModel == FOCUS_CLICK && !(np->state.status & STAT_NOFOCUS)) { FocusClient(np); } } else { JXMapWindow(display, event->window); } JXSync(display, False); JXUngrabServer(display); } else { if(!(np->state.status & STAT_MAPPED)) { np->state = ReadWindowState(np->window); np->state.status |= STAT_MAPPED; if(!(np->state.status & STAT_STICKY)) { np->state.desktop = currentDesktop; } JXMapWindow(display, np->window); JXMapWindow(display, np->parent); if(!(np->state.status & STAT_NOFOCUS)) { RaiseClient(np); FocusClient(np); } UpdateTaskBar(); UpdatePager(); } } RestackClients(); }
/** Handle a map request. */ void HandleMapRequest(const XMapEvent *event) { ClientNode *np; Assert(event); if(CheckSwallowMap(event->window)) { return; } np = FindClientByWindow(event->window); if(!np) { GrabServer(); np = AddClientWindow(event->window, 0, 1); if(np) { if(!(np->state.status & STAT_NOFOCUS)) { FocusClient(np); } } else { JXMapWindow(display, event->window); } UngrabServer(); } else { if(!(np->state.status & STAT_MAPPED)) { UpdateState(np); np->state.status |= STAT_MAPPED; XMapWindow(display, np->window); if(np->parent != None) { XMapWindow(display, np->parent); } if(!(np->state.status & STAT_STICKY)) { np->state.desktop = currentDesktop; } if(!(np->state.status & STAT_NOFOCUS)) { FocusClient(np); RaiseClient(np); } WriteState(np); RequireTaskUpdate(); RequirePagerUpdate(); } } RequireRestack(); }
/** Load windows that are already mapped. */ void StartupClients(void) { XWindowAttributes attr; Window rootReturn, parentReturn, *childrenReturn; unsigned int childrenCount; unsigned int x; clientCount = 0; activeClient = NULL; currentDesktop = 0; /* Clear out the client lists. */ for(x = 0; x < LAYER_COUNT; x++) { nodes[x] = NULL; nodeTail[x] = NULL; } /* Query client windows. */ JXQueryTree(display, rootWindow, &rootReturn, &parentReturn, &childrenReturn, &childrenCount); /* Add each client. */ for(x = 0; x < childrenCount; x++) { if(JXGetWindowAttributes(display, childrenReturn[x], &attr)) { if(attr.override_redirect == False && attr.map_state == IsViewable) { AddClientWindow(childrenReturn[x], 1, 1); } } } JXFree(childrenReturn); LoadFocus(); RequireTaskUpdate(); RequirePagerUpdate(); }
/** 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); }
/** 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); }