void KWM::close(Window w){ static Atom a = 0; if (!a) a = XInternAtom(qt_xdisplay(), "WM_DELETE_WINDOW", False); static Atom ap = 0; if (!ap) ap = XInternAtom(qt_xdisplay(), "WM_PROTOCOLS", False); // clients with WM_DELETE_WINDOW protocol set are // closed via wm_delete_window ClientMessage. // Others are destroyed. Atom *p; int i,n; if (XGetWMProtocols(qt_xdisplay(), w, &p, &n)){ for (i = 0; i < n; i++){ if (p[i] == a){ sendClientMessage(w, ap, a); XFree((char*)p); return; } } if (n>0) XFree(p); } // client will not react on wm_delete_window. We have no choice // but destroy his connection to the XServer. XKillClient(qt_xdisplay(), w); }
void kill_launched_win(Window win) { int i, n, found = 0; Atom *protocols; XEvent e; if (XGetWMProtocols(dpy, win, &protocols, &n)) { for (i=0; i<n; i++) if (protocols[i] == atom_wm_delete) found++; XFree(protocols); } if (found) { e.type = ClientMessage; e.xclient.window = win; e.xclient.message_type = atom_wm_protos; e.xclient.format = 32; e.xclient.data.l[0] = atom_wm_delete; e.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, win, False, NoEventMask, &e); } else { XKillClient(dpy, win); } }
void KWM::enableSessionManagement(Window w){ static Atom a = 0; if (!a) a = XInternAtom(qt_xdisplay(), "WM_SAVE_YOURSELF", False); static Atom b = 0; if (!b) b = XInternAtom(qt_xdisplay(), "KWM_SAVE_YOURSELF", False); Atom *p; int i,n; if (XGetWMProtocols(qt_xdisplay(), w, &p, &n)){ for (i = 0; i < n; i++){ if (p[i] == a) return; } Atom *pn = new Atom[n+1]; for (i=0; i<n; i++) pn[i] = p[i]; pn[i] = a; XSetWMProtocols(qt_xdisplay(), w, pn, n+1); if (n>0) XFree((char*)p); delete[] pn; } else XSetWMProtocols(qt_xdisplay(), w, &a, 1); setSimpleProperty(w, b, 1); }
EAPI Eina_Bool ecore_x_window_prop_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol) { Atom proto, *protos = NULL; int i, protos_count = 0; Eina_Bool ret = EINA_FALSE; /* check for invalid values */ if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE; LOGFN(__FILE__, __LINE__, __FUNCTION__); proto = _ecore_x_atoms_wm_protocols[protocol]; ret = XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count); if (_ecore_xlib_sync) ecore_x_sync(); if (!ret) return ret; for (i = 0; i < protos_count; i++) if (protos[i] == proto) { ret = EINA_TRUE; break; } XFree(protos); return ret; }
static void handle_top_level(Display * display, Window window, Atom protocols_atom, Atom delete_window_atom) { Atom *prots; int nprots, j; if (has_property(display, window, protocols_atom)) { XGetWMProtocols(display, window, &prots, &nprots); if (err_occurred) return; for (j = 0; j < nprots; j++) if (prots[j] == delete_window_atom) { send_delete_message(display, window, protocols_atom, delete_window_atom); break; } if (j == nprots) /* delete window not found */ XKillClient(display, window); XFree((caddr_t) prots); } else XKillClient(display, window); }
void Frame::get_wm_protocols() { Atom *protocols; int nprot,i; prot_delete = false; prot_take_focus = false; Atom wm_delete_window = XInternAtom(QX11Info::display(), "WM_DELETE_WINDOW", False); Atom wm_take_focus = XInternAtom(QX11Info::display(), "WM_TAKE_FOCUS", False); if (XGetWMProtocols(QX11Info::display(), c_win, &protocols, &nprot)) { for (i=0; i < nprot; i++) { if (protocols[i] == wm_delete_window) { prot_delete = true; } else if (protocols[i] == wm_take_focus) { prot_take_focus = true; } } XFree(protocols); } }
/* protocols_return is really Atom**, but to avoid extra includes, we'll use void* */ Status count_xgetwmprotocols (const char *fname, int line, Display * display, Window w, void *protocols_return, int *count_return) { Status val; val = XGetWMProtocols (display, w, (Atom **) protocols_return, count_return); if (val && *count_return) count_alloc (fname, line, *(void **)protocols_return, *count_return * sizeof (Atom), C_XMEM | C_XGETWMPROTOCOLS); return val; }
Bool isprotodel(Client *c) { int i, n; Atom *protocols; Bool ret = False; if(XGetWMProtocols(dpy, c->win, &protocols, &n)) { for(i = 0; !ret && i < n; i++) if(protocols[i] == wmatom[WMDelete]) ret = True; XFree(protocols); } return ret; }
void send_wm_delete(Client *c, int kill_client) { int i, n, found = 0; Atom *protocols; if (!kill_client && XGetWMProtocols(dpy, c->window, &protocols, &n)) { for (i = 0; i < n; i++) if (protocols[i] == xa_wm_delete) found++; XFree(protocols); } if (found) send_xmessage(c->window, xa_wm_protos, xa_wm_delete); else XKillClient(dpy, c->window); }
/* stolen from gwmh */ static gboolean wm_protocol_check_support (Window xwin, Atom check_atom) { Atom *pdata = NULL; guint32 *gdata = NULL; int n_pids = 0; gboolean is_supported = FALSE; guint i, n_gids = 0; trap_push (); if (!XGetWMProtocols (wm_disp, xwin, &pdata, &n_pids)) { gint size = 0; gdata = get_typed_property_data (wm_disp, xwin, XA_WM_PROTOCOLS, XA_WM_PROTOCOLS, &size, 32); n_gids = size / 4; } trap_pop (); for (i = 0; i < n_pids; i++) if (pdata[i] == check_atom) { is_supported = TRUE; break; } if (pdata) XFree (pdata); if (!is_supported) for (i = 0; i < n_gids; i++) if (gdata[i] == check_atom) { is_supported = TRUE; break; } g_free (gdata); return is_supported; }
void UpdateWMProtocols(UltimateContext *uc) { Atom *prots; int count,a; uc->ProtocolFlags=0; if(XGetWMProtocols(disp,uc->win,&prots,&count)) { for(a=0;a<count;a++){ if(prots[a]==WM_TAKE_FOCUS) { uc->ProtocolFlags|=TAKE_FOCUS; if(uc == ActiveWin) SendWMProtocols(uc, WM_TAKE_FOCUS); } if(prots[a]==WM_DELETE_WINDOW) uc->ProtocolFlags|=DELETE_WINDOW; } XFree(prots); } }
void Client::getWMProtocols(void) { Atom *protocols; int nprot,i; protDelete = false; protTakeFocus = false; if (XGetWMProtocols(display(), clientId, &protocols, &nprot)) { for (i=0; i < nprot; i++) { if (protocols[i] == Atoms::atom(Atoms::WM_DELETE_WINDOW)) { protDelete = true; } else if (protocols[i] == Atoms::atom(Atoms::WM_TAKE_FOCUS)) { protTakeFocus = true; } } XFree(protocols); } }
void clientwin_get_protocols(WClientWin *cwin) { Atom *protocols=NULL, *p; int n; cwin->flags&=~(CLIENTWIN_P_WM_DELETE|CLIENTWIN_P_WM_TAKE_FOCUS); if(!XGetWMProtocols(ioncore_g.dpy, cwin->win, &protocols, &n)) return; for(p=protocols; n; n--, p++){ if(*p==ioncore_g.atom_wm_delete) cwin->flags|=CLIENTWIN_P_WM_DELETE; else if(*p==ioncore_g.atom_wm_take_focus) cwin->flags|=CLIENTWIN_P_WM_TAKE_FOCUS; } if(protocols!=NULL) XFree((char*)protocols); }
void send_wm_delete(Client *c) { int n, found = 0; Atom *protocols; if (c) { if (XGetWMProtocols(dpy, c->window, &protocols, &n)) { for (int i = 0; i < n; i++) if (protocols[i] == xa_wm_delete) found++; XFree(protocols); } if (found) send_xmessage(c->window, xa_wm_protos, xa_wm_delete); else XKillClient(dpy, c->window); } next(NULL); }
void PropGetProtocols(Window window, WProtocols *prots) { Atom *protocols; int count, i; memset(prots, 0, sizeof(WProtocols)); if (!XGetWMProtocols(dpy, window, &protocols, &count)) { return; } for (i = 0; i < count; i++) { if (protocols[i] == w_global.atom.wm.take_focus) prots->TAKE_FOCUS = 1; else if (protocols[i] == w_global.atom.wm.delete_window) prots->DELETE_WINDOW = 1; else if (protocols[i] == w_global.atom.wm.save_yourself) prots->SAVE_YOURSELF = 1; else if (protocols[i] == w_global.atom.gnustep.wm_miniaturize_window) prots->MINIATURIZE_WINDOW = 1; } XFree(protocols); }
void icccm_send_client_message(Client *c, Atom msg) { int i, n; Atom *protocols; if (XGetWMProtocols(disp, c->window, &protocols, &n)) { for (i = 0; i < n; i++) if (protocols[i] == msg) { XEvent xcm; xcm.type = ClientMessage; xcm.xclient.window = c->window; xcm.xclient.message_type = XInternAtom(disp, "WM_PROTOCOLS", False); xcm.xclient.format = 32; xcm.xclient.data.l[0] = msg; xcm.xclient.data.l[1] = CurrentTime; XSendEvent(disp, c->window, False, NoEventMask, &xcm); } XFree(protocols); } }
/** * @brief Get a array containing the protocols of @a win * @note If there aren't any properties to be counted or any protocols to get * then the function returns NULL. * @param win The window for which protocol list will be got. * @param num_ret Contains the number of elements of the array to be returned. * @return The array that contains the protocols. */ EAPI Ecore_X_WM_Protocol * ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret) { Atom *protos = NULL; int i, protos_count = 0; Ecore_X_WM_Protocol *prot_ret = NULL; Eina_Bool success; LOGFN(__FILE__, __LINE__, __FUNCTION__); success = XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count); if (_ecore_xlib_sync) ecore_x_sync(); if (!success) return NULL; if ((!protos) || (protos_count <= 0)) return NULL; prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol)); if (!prot_ret) { XFree(protos); return NULL; } for (i = 0; i < protos_count; i++) { Ecore_X_WM_Protocol j; prot_ret[i] = -1; for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++) { if (_ecore_x_atoms_wm_protocols[j] == protos[i]) prot_ret[i] = j; } } XFree(protos); *num_ret = protos_count; return prot_ret; }
void manager_interpret_message( Display *conn, XClientMessageEvent event ) { frame_t *frame = frame_get( event.window ); if (event.message_type == EA_NET_CLOSE_WINDOW ) { printf( "\t_NET_CLOSE_WINDOW\n" ); /* Close the application */ Window window = frame->child->id; Atom *protocols; int num, i; XUnmapWindow( conn, window ); XGetWMProtocols( conn, window, &protocols, &num ); for (i = 0; i < num; i++ ) { if ( protocols[i] == XA_WM_DELETE_WINDOW ) { XEvent event_send; event_send.type = ClientMessage; event_send.xclient.type = ClientMessage; event_send.xclient.message_type = XA_WM_PROTOCOLS; event_send.xclient.format = 32; event_send.xclient.data.l[0] = XA_WM_DELETE_WINDOW; event_send.xclient.data.l[1] = event.data.l[0]; XSendEvent( conn, window, False, 0, &event_send ); window = None; } } if ( window != None ) XKillClient( conn, window ); } else if ( event.message_type == EA_NET_MOVERESIZE_WINDOW ) { /* Change the window position on client request */ if ( event.data.l[0] & (MR_FLAG_X | MR_FLAG_Y) ) frame_move( conn, frame, event.data.l[1], event.data.l[2] ); } else if ( event.message_type == EA_NET_ACTIVE_WINDOW ) { /* Change the window focus on client request */ frame_focus( conn, frame ); } }
// mainly from dwm.c bool client_sendevent(HSClient *client, Atom proto) { int n; Atom *protocols; bool exists = false; XEvent ev; if (XGetWMProtocols(g_display, client->window, &protocols, &n)) { while (!exists && n--) exists = protocols[n] == proto; XFree(protocols); } if (exists) { ev.type = ClientMessage; ev.xclient.window = client->window; ev.xclient.message_type = g_wmatom[WMProtocols]; ev.xclient.format = 32; ev.xclient.data.l[0] = proto; ev.xclient.data.l[1] = CurrentTime; XSendEvent(g_display, client->window, False, NoEventMask, &ev); } return exists; }
/** * Set or unset a wm protocol property. * @param win The Window * @param protocol The protocol to enable/disable * @param on On/Off */ EAPI void ecore_x_icccm_protocol_set(Ecore_X_Window win, Ecore_X_WM_Protocol protocol, Eina_Bool on) { Atom *protos = NULL; Atom proto; int protos_count = 0; int already_set = 0; int i; /* Check for invalid values */ if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return; LOGFN(__FILE__, __LINE__, __FUNCTION__); proto = _ecore_x_atoms_wm_protocols[protocol]; if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) { protos = NULL; protos_count = 0; } if (_ecore_xlib_sync) ecore_x_sync(); for (i = 0; i < protos_count; i++) { if (protos[i] == proto) { already_set = 1; break; } } if (on) { Atom *new_protos = NULL; if (already_set) goto leave; new_protos = malloc((protos_count + 1) * sizeof(Atom)); if (!new_protos) goto leave; for (i = 0; i < protos_count; i++) new_protos[i] = protos[i]; new_protos[protos_count] = proto; XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1); if (_ecore_xlib_sync) ecore_x_sync(); free(new_protos); } else { if (!already_set) goto leave; for (i = 0; i < protos_count; i++) { if (protos[i] == proto) { int j; for (j = i + 1; j < protos_count; j++) protos[j - 1] = protos[j]; if (protos_count > 1) XSetWMProtocols(_ecore_x_disp, win, protos, protos_count - 1); else XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_PROTOCOLS); if (_ecore_xlib_sync) ecore_x_sync(); goto leave; } } } leave: if (protos) XFree(protos); }
/** @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); } }
static void * winMultiWindowWMProc (void *pArg) { WMProcArgPtr pProcArg = (WMProcArgPtr)pArg; WMInfoPtr pWMInfo = pProcArg->pWMInfo; /* Initialize the Window Manager */ winInitMultiWindowWM (pWMInfo, pProcArg); #if CYGMULTIWINDOW_DEBUG ErrorF ("winMultiWindowWMProc ()\n"); #endif /* Loop until we explicity break out */ for (;;) { WMMsgNodePtr pNode; /* Pop a message off of our queue */ pNode = PopMessage (&pWMInfo->wmMsgQueue); if (pNode == NULL) { /* Bail if PopMessage returns without a message */ /* NOTE: Remember that PopMessage is a blocking function. */ ErrorF ("winMultiWindowWMProc - Queue is Empty?\n"); pthread_exit (NULL); } #if CYGMULTIWINDOW_DEBUG ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n", GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID); #endif /* Branch on the message type */ switch (pNode->msg.msg) { #if 0 case WM_WM_MOVE: ErrorF ("\tWM_WM_MOVE\n"); break; case WM_WM_SIZE: ErrorF ("\tWM_WM_SIZE\n"); break; #endif case WM_WM_RAISE: #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_RAISE\n"); #endif /* Raise the window */ XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow); break; case WM_WM_LOWER: #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_LOWER\n"); #endif /* Lower the window */ XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow); break; case WM_WM_MAP: #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_MAP\n"); #endif { XWindowAttributes attr; char *pszName; #if 0 XWMHints *pHints; #endif /* Get the window attributes */ XGetWindowAttributes (pWMInfo->pDisplay, pNode->msg.iWindow, &attr); if (!attr.override_redirect) { /* Set the Windows window name */ GetWindowName(pWMInfo->pDisplay, pNode->msg.iWindow, &pszName); SetWindowText (pNode->msg.hwndWindow, pszName); free (pszName); } } break; case WM_WM_UNMAP: #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_UNMAP\n"); #endif /* Unmap the window */ XUnmapWindow(pWMInfo->pDisplay, pNode->msg.iWindow); break; case WM_WM_KILL: #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_KILL\n"); #endif { int i, n, found = 0; Atom *protocols; /* --- */ if (XGetWMProtocols (pWMInfo->pDisplay, pNode->msg.iWindow, &protocols, &n)) { for (i = 0; i < n; ++i) if (protocols[i] == pWMInfo->atmWmDelete) ++found; XFree (protocols); } /* --- */ if (found) SendXMessage (pWMInfo->pDisplay, pNode->msg.iWindow, pWMInfo->atmWmProtos, pWMInfo->atmWmDelete); else XKillClient (pWMInfo->pDisplay, pNode->msg.iWindow); } break; case WM_WM_ACTIVATE: #if CYGMULTIWINDOW_DEBUG ErrorF ("\tWM_WM_ACTIVATE\n"); #endif /* Set the input focus */ XSetInputFocus (pWMInfo->pDisplay, pNode->msg.iWindow, RevertToPointerRoot, CurrentTime); break; case WM_WM_X_EVENT: /* Process all X events in the Window Manager event queue */ FlushXEvents (pWMInfo); break; default: ErrorF ("winMultiWindowWMProc - Unknown Message.\n"); pthread_exit (NULL); break; } /* Free the retrieved message */ free (pNode); /* Flush any pending events on our display */ XFlush (pWMInfo->pDisplay); } /* Free the condition variable */ pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty); /* Free the mutex variable */ pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex); /* Free the passed-in argument */ free (pProcArg); #if CYGMULTIWINDOW_DEBUG ErrorF("-winMultiWindowWMProc ()\n"); #endif }
/*********************************************************************** * Event Handler to reparent client window under plugin window ***********************************************************************/ /* static */ void SubstructureRedirectHandler ( Widget widget, XtPointer client_data, XEvent* event, Boolean* cont) { windowrec* new_list; PluginInstance* This = (PluginInstance*) client_data; #ifdef PLUGIN_TRACE fprintf (stderr, "%s\n", "SubstructureRedirectHandler"); fprintf (stderr, "This: 0x%x\n", This); #endif switch (event->type) { case ConfigureRequest: { XWindowChanges config; config.x = event->xconfigurerequest.x; config.y = event->xconfigurerequest.y; config.width = event->xconfigurerequest.width; config.height = event->xconfigurerequest.height; config.border_width = event->xconfigurerequest.border_width; config.sibling = event->xconfigurerequest.above; config.stack_mode = event->xconfigurerequest.detail; #if 0 fprintf (stderr, "configuring at %dx%d+%d+%d\n", config.width, config.height, config.x, config.y); #endif XConfigureWindow (RxGlobal.dpy, event->xconfigurerequest.window, event->xconfigurerequest.value_mask, &config); } break; case MapRequest: RxpSetStatusWidget(This, RUNNING); { Window for_win; int i; if (XGetTransientForHint (RxGlobal.dpy, event->xmaprequest.window, &for_win)) { for (i = 0; i < This->nclient_windows; i++) if (for_win == This->client_windows[i].win) XMapWindow (RxGlobal.dpy, event->xmaprequest.window); return; } } new_list = (windowrec*) NPN_MemAlloc (sizeof (windowrec) * (This->nclient_windows + 1)); if (new_list) { Position x, y; Dimension width, height; Dimension border_width; Colormap cmap; int n; Atom* wm_proto; windowrec* wp; Window destwin = XtWindow (This->plugin_widget); This->nclient_windows++; if (This->nclient_windows > 1) memcpy ((void*) new_list, (void*) This->client_windows, (This->nclient_windows - 1) * sizeof (windowrec)); if (This->client_windows) NPN_MemFree (This->client_windows); This->client_windows = new_list; x = y = 0; width = height = border_width = 0; GetWindowGeometry (RxGlobal.dpy, event->xmaprequest.window, &x, &y, &width, &height, &border_width, &cmap); wp = &This->client_windows[This->nclient_windows - 1]; wp->win = event->xmaprequest.window; wp->x = x; wp->y = y; wp->width = width; wp->height = height; wp->border_width = border_width; wp->flags = RxpMapped; wp->colormap = cmap; if (XGetWMProtocols (RxGlobal.dpy, wp->win, &wm_proto, &n)) { int i; Atom* ap; for (i = 0, ap = wm_proto; i < n; i++, ap++) { if (*ap == RxGlobal.wm_delete_window) wp->flags |= RxpWmDelWin; } if (wm_proto) XFree ((char*) wm_proto); } XSelectInput(RxGlobal.dpy, wp->win, EnterWindowMask | LeaveWindowMask); XtRegisterDrawable (RxGlobal.dpy, wp->win, This->plugin_widget); XReparentWindow (RxGlobal.dpy, wp->win, destwin, wp->x, wp->y); XMapWindow (RxGlobal.dpy, wp->win); } break; } }
void KSMServer::performLegacySessionSave() { kdDebug( 1218 ) << "Saving legacy session apps" << endl; // Setup error handler legacyWindows.clear(); windowMapPtr = &legacyWindows; XErrorHandler oldHandler = XSetErrorHandler(winsErrorHandler); // Compute set of leader windows that need legacy session management // and determine which style (WM_COMMAND or WM_SAVE_YOURSELF) KWinModule module; if( wm_save_yourself == (Atom)None ) { Atom atoms[ 3 ]; const char* const names[] = { "WM_SAVE_YOURSELF", "WM_PROTOCOLS", "WM_CLIENT_LEADER" }; XInternAtoms( tqt_xdisplay(), const_cast< char** >( names ), 3, False, atoms ); wm_save_yourself = atoms[ 0 ]; wm_protocols = atoms[ 1 ]; wm_client_leader = atoms[ 2 ]; } for ( TQValueList<WId>::ConstIterator it = module.windows().begin(); it != module.windows().end(); ++it) { WId leader = windowWmClientLeader( *it ); if (!legacyWindows.contains(leader) && windowSessionId( *it, leader ).isEmpty()) { SMType wtype = SM_WMCOMMAND; int nprotocols = 0; Atom *protocols = 0; if( XGetWMProtocols(tqt_xdisplay(), leader, &protocols, &nprotocols)) { for (int i=0; i<nprotocols; i++) if (protocols[i] == wm_save_yourself) { wtype = SM_WMSAVEYOURSELF; break; } XFree((void*) protocols); } SMData data; data.type = wtype; XClassHint classHint; if( XGetClassHint( tqt_xdisplay(), leader, &classHint ) ) { data.wmclass1 = classHint.res_name; data.wmclass2 = classHint.res_class; XFree( classHint.res_name ); XFree( classHint.res_class ); } legacyWindows.insert(leader, data); } } // Open fresh display for sending WM_SAVE_YOURSELF XSync(tqt_xdisplay(), False); Display *newdisplay = XOpenDisplay(DisplayString(tqt_xdisplay())); if (!newdisplay) { windowMapPtr = NULL; XSetErrorHandler(oldHandler); return; } WId root = DefaultRootWindow(newdisplay); XGrabKeyboard(newdisplay, root, False, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(newdisplay, root, False, Button1Mask|Button2Mask|Button3Mask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); // Send WM_SAVE_YOURSELF messages XEvent ev; int awaiting_replies = 0; for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { if ( (*it).type == SM_WMSAVEYOURSELF ) { WId w = it.key(); awaiting_replies += 1; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = wm_protocols; ev.xclient.format = 32; ev.xclient.data.l[0] = wm_save_yourself; ev.xclient.data.l[1] = GET_QT_X_TIME(); XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask); XSendEvent(newdisplay, w, False, 0, &ev); } } // Wait for change in WM_COMMAND with timeout XFlush(newdisplay); TQTime start = TQTime::currentTime(); while (awaiting_replies > 0) { if (XPending(newdisplay)) { /* Process pending event */ XNextEvent(newdisplay, &ev); if ( ( ev.xany.type == UnmapNotify ) || ( ev.xany.type == PropertyNotify && ev.xproperty.atom == XA_WM_COMMAND ) ) { WindowMap::Iterator it = legacyWindows.find( ev.xany.window ); if ( it != legacyWindows.end() && (*it).type != SM_WMCOMMAND ) { awaiting_replies -= 1; if ( (*it).type != SM_ERROR ) (*it).type = SM_WMCOMMAND; } } } else { /* Check timeout */ int msecs = start.elapsed(); if (msecs >= WM_SAVE_YOURSELF_TIMEOUT) break; /* Wait for more events */ fd_set fds; FD_ZERO(&fds); int fd = ConnectionNumber(newdisplay); FD_SET(fd, &fds); struct timeval tmwait; tmwait.tv_sec = (WM_SAVE_YOURSELF_TIMEOUT - msecs) / 1000; tmwait.tv_usec = ((WM_SAVE_YOURSELF_TIMEOUT - msecs) % 1000) * 1000; ::select(fd+1, &fds, NULL, &fds, &tmwait); } } // Terminate work in new display XAllowEvents(newdisplay, ReplayPointer, CurrentTime); XAllowEvents(newdisplay, ReplayKeyboard, CurrentTime); XSync(newdisplay, False); XCloseDisplay(newdisplay); // Restore old error handler XSync(tqt_xdisplay(), False); XSetErrorHandler(oldHandler); for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { if ( (*it).type != SM_ERROR) { WId w = it.key(); (*it).wmCommand = windowWmCommand(w); (*it).wmClientMachine = windowWmClientMachine(w); } } kdDebug( 1218 ) << "Done saving " << legacyWindows.count() << " legacy session apps" << endl; }