void flushclients() { unsigned int i, nwins; Window dw1, dw2, *wins; Client *c; #ifdef ASSIMILATE_WINDOWS Scrn *scr2; #endif if((scr = front)) do { scr = scr->upfront; XQueryTree(dpy, scr->back, &dw1, &dw2, &wins, &nwins); for(i=0; i<nwins; i++) if((!XFindContext(dpy, wins[i], client_context, (XPointer *)&c))&&wins[i]==c->parent) { int x,y; grav_map_frame_to_win(c, c->x, c->y, &x, &y); XReparentWindow(dpy, c->window, scr->root, x, y); XSetWindowBorderWidth(dpy, c->window, c->old_bw); XRemoveFromSaveSet(dpy, c->window); wins[i]=c->window; rmclient(c); } #ifdef ASSIMILATE_WINDOWS else if((!XFindContext(dpy, wins[i], screen_context, (XPointer *)&scr2)) && scr2==scr) { XWindowAttributes attr; XSetWindowAttributes xsa; XGetWindowAttributes(dpy, wins[i], &attr); XReparentWindow(dpy, wins[i], scr->root, attr.x, attr.y); xsa.override_redirect = True; XChangeWindowAttributes(dpy, wins[i], CWOverrideRedirect, &xsa); XDeleteContext(dpy, wins[i], screen_context); XRemoveFromSaveSet(dpy, wins[i]); } #endif /* if(nwins) { for(i=0; i<(nwins>>1); i++) { Window w=wins[i]; wins[i]=wins[nwins-1-i]; wins[nwins-1-i]=w; } XRestackWindows(dpy, wins, nwins); } */ XFree((void *) wins); } while(scr!=front); while((c=clients)) { if(c->parent != c->scr->root) { int x,y; grav_map_frame_to_win(c, c->x, c->y, &x, &y); XReparentWindow(dpy, c->window, c->scr->root, x, y); XSetWindowBorderWidth(dpy, c->window, c->old_bw); XRemoveFromSaveSet(dpy, c->window); } rmclient(c); } }
static void remove_window (Window w) { GList *li = find_window_list (w, FALSE); if (w == wm_focus_window) wm_focus_window = None; if (li != NULL) { MdmWindow *gw = li->data; li->data = NULL; trap_push (); XRemoveFromSaveSet (wm_disp, w); gw->win = None; if (gw->deco != None) { XDestroyWindow (wm_disp, gw->deco); gw->deco = None; } if (gw->shadow != None) { XDestroyWindow (wm_disp, gw->shadow); gw->shadow = None; } trap_pop (); windows = g_list_remove_link (windows, li); g_list_free_1 (li); g_free (gw); } }
void qapp::wm_restart(void) { xwindow *client; int i; if(smode) keyboard::tscreen(); for(i=0; i < defaults::vdesks; i++) { if(tdesks[i]) { tb_pg->change_desk(i); toggle_tiled(); } } winf->release_cancel(); tb_pg->change_desk(0); tb_pb->remove_all(); foreach(client, clients) { XRemoveFromSaveSet(QX11Info::display(), client->client_id()); XReparentWindow(QX11Info::display(), client->client_id(), QX11Info::appRootWindow(), client->x(), client->y()); XMapWindow(QX11Info::display(), client->client_id()); }
void qapp::wm_restart(void) { xwindow *client; int i; //if(smode) // keyboard::tscreen(); for(i=0; i < defaults::vdesks; i++) { if(tdesks[i]) { HomeDesktop::instance()->getPager()->setActiveDesktop(i); //toggle_tiled(); } } winf->release_cancel(); HomeDesktop::instance()->getPager()->setActiveDesktop(0); foreach(client, clients) { XRemoveFromSaveSet(QX11Info::display(), client->client_id()); XReparentWindow(QX11Info::display(), client->client_id(), QX11Info::appRootWindow(), client->x(), client->y()); XMapWindow(QX11Info::display(), client->client_id()); }
void remove_client(Client *c) { Client *p; LOG_DEBUG("remove_client() : Removing...\n"); if (!c || !c->xstuff) return; XGrabServer(dpy); ignore_xerror = 1; /* ICCCM 4.1.3.1 * "When the window is withdrawn, the window manager will either * change the state field's value to WithdrawnState or it will * remove the WM_STATE property entirely." * EWMH 1.3 * "The Window Manager should remove the property whenever a * window is withdrawn but it should leave the property in * place when it is shutting down." (both _NET_WM_DESKTOP and * _NET_WM_STATE) */ if (c->remove) { LOG_DEBUG("\tremove_client() : setting WithdrawnState\n"); set_wm_state(c, WithdrawnState); XDeleteProperty(dpy, c->xstuff->window, xa_net_wm_desktop); XDeleteProperty(dpy, c->xstuff->window, xa_net_wm_state); } ungravitate(c); if (c->xstuff->screen) XReparentWindow(dpy, c->xstuff->window, c->xstuff->screen->root, c->x, c->y); XSetWindowBorderWidth(dpy, c->xstuff->window, c->old_border); XRemoveFromSaveSet(dpy, c->xstuff->window); if (c->xstuff->parent) XDestroyWindow(dpy, c->xstuff->parent); if (head_client == c) head_client = c->next; else for (p = head_client; p && p->next; p = p->next) if (p->next == c) p->next = c->next; if (current == c) current = NULL; /* an enter event should set this up again */ free(c->xstuff); free(c); #ifdef DEBUG { Client *pp; int i = 0; for (pp = head_client; pp; pp = pp->next) i++; LOG_DEBUG("\tremove_client() : free(), window count now %d\n", i); } #endif XUngrabServer(dpy); XFlush(dpy); ignore_xerror = 0; LOG_DEBUG("remove_client() returning\n"); }
void del_client(client_t *c, int mode) { client_t *p; XGrabServer(dpy); XSetErrorHandler(ignore_xerror); #ifdef DEBUG dump_name(c, "removing", 'r'); dump_removal(c, mode); #endif if (mode == DEL_WITHDRAW) { set_wm_state(c, WithdrawnState); } else /* mode == DEL_REMAP */ { if (c->zoomed) { c->geom.x = c->save.x; c->geom.y = c->save.y; c->geom.w = c->save.w; c->geom.h = c->save.h; XResizeWindow(dpy, c->win, c->geom.w, c->geom.h); } XMapWindow(dpy, c->win); } remove_atom(root, net_client_list, XA_WINDOW, c->win); remove_atom(root, net_client_stack, XA_WINDOW, c->win); XSetWindowBorderWidth(dpy, c->win, c->old_bw); #ifdef XFT if (c->xftdraw) XftDrawDestroy(c->xftdraw); #endif XReparentWindow(dpy, c->win, root, c->geom.x, c->geom.y); XRemoveFromSaveSet(dpy, c->win); XDestroyWindow(dpy, c->frame); if (head == c) head = c->next; else for (p = head; p && p->next; p = p->next) if (p->next == c) p->next = c->next; if (c->name) XFree(c->name); free(c); XSync(dpy, False); XSetErrorHandler(handle_xerror); XUngrabServer(dpy); }
void remove_client(Client *c, int from_cleanup) { Client *p = NULL; XGrabServer(dpy); XSetErrorHandler(ignore_xerror); if (c->name && c->name != null_str) XFree(c->name); if (from_cleanup) unhide(c, NO_RAISE); else if (!from_cleanup) set_wm_state(c, WithdrawnState); ungravitate(c); XReparentWindow(dpy, c->window, root, c->x, c->y); XRemoveFromSaveSet(dpy, c->window); XSetWindowBorderWidth(dpy, c->window, 1); XDestroyWindow(dpy, c->parent); if (head_client == c) head_client = c->next; else { for (p = head_client; p && p->next; p = p->next) if (p->next == c) p->next = c->next; } if (c->size) XFree(c->size); /* an enter event should set this up again */ if (c == current) { current = NULL; if (prev_focused[c->vdesk] == c) prev_focused[c->vdesk] = NULL; } free(c); XSync(dpy, False); XSetErrorHandler(handle_xerror); XUngrabServer(dpy); }
void Client::withdraw(Boolean changeState) { // fprintf(stderr,"withdrawing\n"); m_border->unmap(); gravitate(True); XReparentWindow(display(), m_window, root(), m_x, m_y); gravitate(False); if (changeState) { XRemoveFromSaveSet(display(), m_window); setState(WithdrawnState); } ignoreBadWindowErrors = True; XSync(display(), False); ignoreBadWindowErrors = False; }
void qapp::wm_restart(void) { xwindow *client; int i; QString fname = get_cfile("defaults"); if(fname.isNull()) return; QFileInfo fi(fname); if(fi.lastModified() == lmtime || fi.lastModified().addSecs(180) < QDateTime::currentDateTime()) return; lmtime = fi.lastModified(); if(smode) keyboard::tscreen(); for(i=0; i < defaults::vdesks; i++) { if(tdesks[i]) { tb_pg->change_desk(i); toggle_tiled(); } } winf->release_cancel(); tb_pg->change_desk(0); tb_pb->remove_all(); for(client = clients.first(); client != NULL; client = clients.next()) { XRemoveFromSaveSet(qt_xdisplay(), client->client_id()); XReparentWindow(qt_xdisplay(), client->client_id(), qt_xrootwin(), client->x(), client->y()); XMapWindow(qt_xdisplay(), client->client_id()); } clients.clear(); tb_ap->release_all(); delete tb; XSync(qt_xdisplay(), FALSE); char *argv[20]; int rst=TRUE; for(i=0; i < defaults::argc && i < 18; i++) { argv[i] = defaults::argv[i]; if(strcmp(argv[i], "-restart") == 0) rst = FALSE; } if(rst) argv[i++] = "-restart"; argv[i] = NULL; execvp(argv[0], argv); perror(argv[0]); exit(1); }
/** @brief This function reparents a framed window to root and then destroys the frame. It is used when the framed window has been unmapped or destroyed, or is about to be. @param workspaces list of all workspaces. @param index index of the target frame in the global list of frames @return void **/ void remove_frame(Display* display, struct Workspace_list *workspaces, int index, int current_workspace, struct Atoms *atoms, struct Themes *themes) { struct Frame *frame = &workspaces->frame_list[index]; XWindowChanges changes; Window root = DefaultRootWindow(display); unsigned int mask = CWSibling | CWStackMode; changes.stack_mode = Below; changes.sibling = frame->widgets[frame_parent].widget; free_frame_name(frame); XDestroyWindow(display, frame->menu.item); //make the whole window disappear before the inner frame is unmapped to make it look faster XUnmapWindow(display, frame->widgets[frame_parent].widget); XSync(display, False); #ifdef CRASH_ON_BUG XGrabServer(display); XSetErrorHandler(supress_xerror); #endif XDeleteProperty(display, frame->framed_window, atoms->wm_state); frame->state = none; XReparentWindow(display, frame->framed_window, root , frame->x + themes->window_type[frame->theme_type][window].x , frame->y + themes->window_type[frame->theme_type][window].y); //TODO need to change the frame w,h attributes here //keep the stacking order XConfigureWindow(display, frame->framed_window, mask, &changes); XRemoveFromSaveSet(display, frame->framed_window); //this will not destroy the window because it has been reparented to root XDestroyWindow(display, frame->widgets[frame_parent].widget); XSync(display, False); #ifdef CRASH_ON_BUG XSetErrorHandler(NULL); XUngrabServer(display); #endif //we want to unconditionally remove references to the frame which is being removed in the current workspace if(current_workspace >= 0 && workspaces->list[current_workspace].list) { for(int i = 0; i < workspaces->list[current_workspace].used; i++) { if(workspaces->list[current_workspace].list[i]->framed_window == frame->framed_window) { int nested_last = workspaces->list[current_workspace].used - 1; if((workspaces->list[current_workspace].used != 1) && (i != nested_last) ) { workspaces->list[current_workspace].list[i] = workspaces->list[current_workspace].list[nested_last]; } workspaces->list[current_workspace].used--; break; } } } //make sure that the saved states are reset since it is assumed than an empty slot is zeroed by clean realloc etc. struct Saved_frame_state blank = { .x =0 , .y = 0 , .w = 0, .h = 0, .available = 0, .need_to_tile = 0, .mode = 0, .state = 0 }; for(int i = 0; i < workspaces->used_workspaces; i++) { workspaces->list[i].states[index] = blank; } //remove it from the global frame list, and also remove it's state references. int last = workspaces->used_frames - 1; if((workspaces->used_frames != 1) && (index != last)) { //the frame is not alone or the last struct Frame* last_fp_pointer = &workspaces->frame_list[last]; for(int i = 0; i < workspaces->used_workspaces; i++) { workspaces->list[i].states[index] = workspaces->list[i].states[last]; workspaces->list[i].states[last] = blank; } if(current_workspace >= 0 && workspaces->list[current_workspace].list) { for(int i = 0; i < workspaces->list[current_workspace].used; i++) { //in anticipation of the swap of the last frame we need to update pointers to it. //imagine that the removed frame wasn't in the current workspace (in fact the above code guarantees it) but the moved frame was, it's pointer would become invalid. if(workspaces->list[current_workspace].list[i] == last_fp_pointer) workspaces->list[current_workspace].list[i] = &workspaces->frame_list[index]; } } workspaces->frame_list[index] = workspaces->frame_list[last]; //swap the deleted item with the last item. } workspaces->used_frames--; } /** @brief This function is called when the close button on the frame is pressed. @return void **/ void close_window(Display* display, Window framed_window) { int n; Bool found = False; Atom *protocols; //based on windowlab/aewm if (XGetWMProtocols(display, framed_window, &protocols, &n)) { Atom delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); for (int i = 0; i < n; i++) if (protocols[i] == delete_window) { found = True; break; } XFree(protocols); } if(found) { //from windowlab/aewm XClientMessageEvent event; event.type = ClientMessage; event.window = framed_window; event.format = 32; event.message_type = XInternAtom(display, "WM_PROTOCOLS", False); event.data.l[0] = (long)XInternAtom(display, "WM_DELETE_WINDOW", False); event.data.l[1] = CurrentTime; XSendEvent(display, framed_window, False, NoEventMask, (XEvent *)&event); #ifdef SHOW_UNMAP_NOTIFY_EVENT printf("Sent wm_delete_window message\n"); #endif } else { #ifdef SHOW_UNMAP_NOTIFY_EVENT printf("Killed window %lu\n", (unsigned long)framed_window); #endif XUnmapWindow(display, framed_window); XFlush(display); XKillClient(display, framed_window); } }
/*********************************************************************** * * Procedure: * HandleUnmapNotify - UnmapNotify event handler * ************************************************************************/ void HandleUnmapNotify() { int dstx, dsty; Window dumwin; XEvent dummy; extern FvwmWindow *colormap_win; int weMustUnmap; DBUG("HandleUnmapNotify","Routine Entered"); /* * Don't ignore events as described below. */ if((Event.xunmap.event != Event.xunmap.window) && (Event.xunmap.event != Scr.Root || !Event.xunmap.send_event)) { return; } /* * The July 27, 1988 ICCCM spec states that a client wishing to switch * to WithdrawnState should send a synthetic UnmapNotify with the * event field set to (pseudo-)root, in case the window is already * unmapped (which is the case for fvwm for IconicState). Unfortunately, * we looked for the FvwmContext using that field, so try the window * field also. */ weMustUnmap = 0; if (!Tmp_win) { Event.xany.window = Event.xunmap.window; weMustUnmap = 1; if (XFindContext(dpy, Event.xany.window, FvwmContext, (caddr_t *)&Tmp_win) == XCNOENT) Tmp_win = NULL; } if(!Tmp_win) return; if(weMustUnmap) XUnmapWindow(dpy, Event.xunmap.window); if(Tmp_win == Scr.Hilite) Scr.Hilite = NULL; if(Scr.PreviousFocus == Tmp_win) Scr.PreviousFocus = NULL; if((Tmp_win == Scr.Focus)&&(Tmp_win->flags & ClickToFocus)) { if(Tmp_win->next) { HandleHardFocus(Tmp_win->next); } else SetFocus(Scr.NoFocusWin,NULL,1); } if(Scr.Focus == Tmp_win) SetFocus(Scr.NoFocusWin,NULL,1); if(Tmp_win == Scr.pushed_window) Scr.pushed_window = NULL; if(Tmp_win == colormap_win) colormap_win = NULL; if ((!(Tmp_win->flags & MAPPED)&&!(Tmp_win->flags&ICONIFIED))) { return; } MyXGrabServer(dpy); if(XCheckTypedWindowEvent (dpy, Event.xunmap.window, DestroyNotify,&dummy)) { Destroy(Tmp_win); MyXUngrabServer (dpy); return; } /* * The program may have unmapped the client window, from either * NormalState or IconicState. Handle the transition to WithdrawnState. * * We need to reparent the window back to the root (so that fvwm exiting * won't cause it to get mapped) and then throw away all state (pretend * that we've received a DestroyNotify). */ if (XTranslateCoordinates (dpy, Event.xunmap.window, Scr.Root, 0, 0, &dstx, &dsty, &dumwin)) { XEvent ev; Bool reparented; reparented = XCheckTypedWindowEvent (dpy, Event.xunmap.window, ReparentNotify, &ev); SetMapStateProp (Tmp_win, WithdrawnState); if (reparented) { if (Tmp_win->old_bw) XSetWindowBorderWidth (dpy, Event.xunmap.window, Tmp_win->old_bw); if((!(Tmp_win->flags & SUPPRESSICON))&& (Tmp_win->wmhints && (Tmp_win->wmhints->flags & IconWindowHint))) XUnmapWindow (dpy, Tmp_win->wmhints->icon_window); } else { RestoreWithdrawnLocation (Tmp_win,False); } XRemoveFromSaveSet (dpy, Event.xunmap.window); XSelectInput (dpy, Event.xunmap.window, NoEventMask); Destroy(Tmp_win); /* do not need to mash event before */ /* * Flush any pending events for the window. */ /* Bzzt! it could be about to re-map */ /* while(XCheckWindowEvent(dpy, Event.xunmap.window, StructureNotifyMask | PropertyChangeMask | ColormapChangeMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask, &dummy)); */ } /* else window no longer exists and we'll get a destroy notify */ MyXUngrabServer(dpy); XFlush (dpy); }