/** * Get the WM_COMMAND property for @a win. * * Return the command of a window. String must be free'd when done with. * * @param win The window. * @param argc Number of arguments. * @param argv Arguments. */ EAPI void ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv) { int i, c; char **v; Eina_Bool success; if (argc) *argc = 0; if (argv) *argv = NULL; LOGFN(__FILE__, __LINE__, __FUNCTION__); success = XGetCommand(_ecore_x_disp, win, &v, &c); if (_ecore_xlib_sync) ecore_x_sync(); if (!success) return; if (c < 1) { if (v) XFreeStringList(v); return; } if (argc) *argc = c; if (argv) { (*argv) = malloc(c * sizeof(char *)); if (!*argv) { XFreeStringList(v); if (argc) *argc = 0; return; } for (i = 0; i < c; i++) { if (v[i]) (*argv)[i] = strdup(v[i]); else (*argv)[i] = strdup(""); } } XFreeStringList(v); }
/*********************************************************************** * * Procedure: * checks to see if we are supposed to take some action now, * finds time for next action to be performed. * ***********************************************************************/ void do_save(void) { struct list *t; char tname[200],loc[30]; FILE *out; char **command_list; int dwidth,dheight,xtermline = 0; int x1,x2,y1,y2,i,command_count; long tVx, tVy; sprintf(tname, "%s/new.xinitrc", getenv( "HOME" ) ); out = fopen( tname, "w+" ); for (t = list_root; t != NULL; t = t->next) { tname[0]=0; x1 = t->frame_x; x2 = ScreenWidth - x1 - t->frame_width - 2; if(x2 < 0) x2 = 0; y1 = t->frame_y; y2 = ScreenHeight - y1 - t->frame_height - 2; if(y2 < 0) y2 = 0; dheight = t->frame_height - t->title_height - 2*t->boundary_width; dwidth = t->frame_width - 2*t->boundary_width; dwidth -= t->base_width ; dheight -= t->base_height ; dwidth /= t->width_inc; dheight /= t->height_inc; if ( t->flags & STICKY ) { tVx = 0; tVy = 0; } else { tVx = Vx; tVy = Vy; } sprintf(tname,"%dx%d",dwidth,dheight); if ((t->gravity == EastGravity) || (t->gravity == NorthEastGravity) || (t->gravity == SouthEastGravity)) sprintf(loc,"-%d",x2); else sprintf(loc,"+%d",x1+(int)tVx); strcat(tname, loc); if((t->gravity == SouthGravity)|| (t->gravity == SouthEastGravity)|| (t->gravity == SouthWestGravity)) sprintf(loc,"-%d",y2); else sprintf(loc,"+%d",y1+(int)tVy); strcat(tname, loc); if ( XGetCommand( dpy, t->id, &command_list, &command_count ) ) { for (i=0; i < command_count; i++) { if ( strncmp( "-geo", command_list[i], 4) == 0) { i++; continue; } if ( strncmp( "-ic", command_list[i], 3) == 0) continue; if ( strncmp( "-display", command_list[i], 8) == 0) { i++; continue; } write_string(out,command_list[i]); if(strstr(command_list[i], "xterm")) { fprintf( out, "-geometry %s ", tname ); if ( t->flags & ICONIFIED ) fprintf(out, "-ic "); xtermline = 1; } } if ( command_count > 0 ) { if ( xtermline == 0 ) { if ( t->flags & ICONIFIED ) fprintf(out, "-ic "); fprintf( out, "-geometry %s &\n", tname ); } else { fprintf( out, "&\n"); } } XFreeStringList( command_list ); xtermline = 0; } } fprintf(out, "fvwm\n"); fclose( out ); exit(0); }
void DockBarExtension::windowAdded(WId win) { // try to read WM_COMMAND int argc; char **argv; QString command; if(XGetCommand(qt_xdisplay(), win, &argv, &argc)) { command = KShell::joinArgs(argv, argc); XFreeStringList(argv); } // try to read wm hints WId resIconwin = 0; XWMHints *wmhints = XGetWMHints(qt_xdisplay(), win); if(0 != wmhints) { // we managed to read wm hints // read IconWindowHint bool is_valid = false; /* a good dockapp set the icon hint and the state hint, if it uses its icon, the window initial state must be "withdrawn" if not, then the initial state must be "normal" this filters the problematic Eterm whose initial state is "normal" and which has an iconwin. */ if((wmhints->flags & IconWindowHint) && (wmhints->flags & StateHint)) { resIconwin = wmhints->icon_window; is_valid = (resIconwin && wmhints->initial_state == 0) || (resIconwin == 0 && wmhints->initial_state == 1); /* an alternative is a window who does not have an icon, but whose initial state is set to "withdrawn". This has been added for wmxmms... I hope it won't swallow to much windows :-/ */ } else if((wmhints->flags & IconWindowHint) == 0 && (wmhints->flags & StateHint)) { is_valid = (wmhints->initial_state == 0); } XFree(wmhints); if(!is_valid) return; // we won't swallow this one } else return; // The following if statement was at one point commented out, // without a comment as to why. This caused problems like // Eterm windows getting swallowed whole. So, perhaps now I'll // get bug reports about whatever commenting it out was supposed // to fix. if(resIconwin == 0) resIconwin = win; // try to read class hint XClassHint hint; QString resClass, resName; if(XGetClassHint(qt_xdisplay(), win, &hint)) { resName = hint.res_name; resClass = hint.res_class; } else { kdDebug() << "Could not read XClassHint of window " << win << endl; return; } /* withdrawing the window prevents kwin from managing the window, which causes the double-launch bug (one instance from the kwin session, and one from the dockbar) bug when kde is restarted */ if(resIconwin != win) { XWithdrawWindow(qt_xdisplay(), win, qt_xscreen()); while(KWin::windowInfo(win, NET::XAWMState).mappingState() != NET::Withdrawn) ; } // add a container embedWindow(resIconwin, command, resName, resClass); saveContainerConfig(); }
static void print_client_properties(Display *dpy, Window w, Bool verbose, int maxcmdlen) { char **cliargv = NULL; int i, cliargc; XTextProperty nametp, machtp, tp; int charsleft = maxcmdlen; /* * get the WM_MACHINE and WM_COMMAND list of strings */ if (!XGetWMClientMachine (dpy, w, &machtp)) { machtp.value = NULL; machtp.encoding = None; } if (!XGetCommand (dpy, w, &cliargv, &cliargc)) { if (machtp.value) XFree ((char *) machtp.value); return; } /* * do header information */ if (verbose) { printf ("Window 0x%lx:\n", w); print_text_field (dpy, " Machine: ", &machtp); if (XGetWMName (dpy, w, &nametp)) { print_text_field (dpy, " Name: ", &nametp); if (nametp.value) XFree ((char *) nametp.value); } } else { print_text_field (dpy, NULL, &machtp); putchar (' '); putchar (' '); } if (machtp.value) XFree ((char *) machtp.value); if (verbose) { if (XGetWMIconName (dpy, w, &tp)) { print_text_field (dpy, " Icon Name: ", &tp); if (tp.value) XFree ((char *) tp.value); } } /* * do the command */ if (verbose) { printf (" Command: "); } for (i = 0; i < cliargc && charsleft > 0; ) { charsleft -= print_quoted_word (cliargv[i], charsleft); i++; if (i < cliargc && charsleft > 0) { putchar (' '); charsleft--; } } putchar ('\n'); XFreeStringList (cliargv); /* * do trailer information */ if (verbose) { XClassHint clh; if (XGetClassHint (dpy, w, &clh)) { printf (" Instance/Class: %s/%s", clh.res_name ? clh.res_name : Nil, clh.res_class ? clh.res_class : Nil); if (clh.res_name) XFree (clh.res_name); if (clh.res_class) XFree (clh.res_class); putchar ('\n'); } } }
void do_save_command(FILE *out, struct list *t, int *curdesk, int emit_wait, int *isfirstline) { char tname[200],loc[30]; char **command_list; int dwidth,dheight,xtermline = 0; int x1,x2,y1,y2,i,command_count; long tVx, tVy; tname[0]=0; x1 = t->frame_x; x2 = ScreenWidth - x1 - t->frame_width - 2; if(x2 < 0) x2 = 0; y1 = t->frame_y; y2 = ScreenHeight - y1 - t->frame_height - 2; if(y2 < 0) y2 = 0; dheight = t->frame_height - t->title_height - 2*t->boundary_width; dwidth = t->frame_width - 2*t->boundary_width; dwidth -= t->base_width ; dheight -= t->base_height ; dwidth /= t->width_inc; dheight /= t->height_inc; if (IS_STICKY(t)) { tVx = 0; tVy = 0; } else { tVx = Vx; tVy = Vy; } sprintf(tname,"%dx%d",dwidth,dheight); if ((t->gravity == EastGravity) || (t->gravity == NorthEastGravity) || (t->gravity == SouthEastGravity)) sprintf(loc,"-%d",x2); else sprintf(loc,"+%d",x1+(int)tVx); strcat(tname, loc); if((t->gravity == SouthGravity)|| (t->gravity == SouthEastGravity)|| (t->gravity == SouthWestGravity)) sprintf(loc,"-%d",y2); else sprintf(loc,"+%d",y1+(int)tVy); strcat(tname, loc); if ( XGetCommand( dpy, t->id, &command_list, &command_count ) ) { if (*curdesk != t->desk) { fprintf( out, "%s\t\"I\" Desk 0 %ld\n", *isfirstline ? "" : "+", t->desk); fflush ( out ); if (*isfirstline) *isfirstline = 0; *curdesk = t->desk; } fprintf( out, "%s\t\t\"I\" Exec ", *isfirstline ? "" : "+"); if (*isfirstline) *isfirstline = 0; fflush ( out ); for (i=0; i < command_count; i++) { if ( strncmp( "-geo", command_list[i], 4) == 0) { i++; continue; } if ( strncmp( "-ic", command_list[i], 3) == 0) continue; if ( strncmp( "-display", command_list[i], 8) == 0) { i++; continue; } write_string(out,command_list[i]); fflush ( out ); if(strstr(command_list[i], "xterm")) { fprintf( out, "-geometry %s ", tname ); if (IS_ICONIFIED(t)) fprintf(out, "-ic "); xtermline = 1; fflush ( out ); } } if ( command_count > 0 ) { if ( xtermline == 0 ) { if (IS_ICONIFIED(t)) fprintf(out, "-ic "); fprintf( out, "-geometry %s &\n", tname); } else { fprintf( out, "&\n"); } } if (emit_wait) { if (t->name) fprintf( out, "+\t\t\"I\" Wait %s\n", t->name); else fprintf( out, "+\t\t\"I\" Wait %s\n", command_list[0]); fflush( out ); } XFreeStringList( command_list ); xtermline = 0; } }
xwindow::xwindow(Window w, QWidget *parent) : QWidget(parent) { dt = QApplication::desktop(); maxstate = 0; mrb = NULL; clientid = w; actpal = TRUE; urgpal = FALSE; cmapwins = NULL; sstate = FALSE; tstate = FALSE; trsize = FALSE; ncmaps = 0; withdrawnstate = unmapped = TRUE; // get ClassHint get_classhint(); clientname = res_class; // get flags for WM_COMMAND char **argv; int argc; if(XGetCommand(QX11Info::display(), w, &argv, &argc) && argc) { int ncm=0; while(1) { command += argv[ncm]; if(argc > ++ncm) command += ' '; else break; } if(clientname.isEmpty() && ! command.isEmpty()) { char *base; if((base = strrchr(argv[0], '/')) == NULL) base = argv[0]; else base++; clientname = base; } XFreeStringList(argv); } clientname = clientname.simplified(); pflags = get_clientflags(); if(pflags & WindowManager::SmallFrame) { uborderh = defaults::lowerborderheight; borderh = 2*uborderh; } else { uborderh = defaults::windowbuttonsize; borderh = defaults::windowbuttonsize+defaults::lowerborderheight; } // check for nonrectangular window shaped = (WindowManager::servershapes)?(query_shape()):(FALSE); if(pflags & WindowManager::NoResize) borderh -= defaults::lowerborderheight; // save window geometry Window root; uint bwidth,depth; XGetGeometry(QX11Info::display(), w, &root, &pos_x, &pos_y, &init_w, &init_h, &bwidth, &depth); base_w = init_w; base_h = init_h; init_h += borderh; // reparent XSetWindowBorderWidth(QX11Info::display(), w, 0); XSetWindowBorderWidth(QX11Info::display(), winId(), 0); XReparentWindow(QX11Info::display(), w, winId(), 0, uborderh); XAddToSaveSet(QX11Info::display(), w); // get TransientForHint transfor = None; XGetTransientForHint(QX11Info::display(), w, &transfor); // set Font setFont(defaults::borderfont); // get colormap and check for WM_COLORMAP_WINDOWS property get_colormaps(); // get WM_CLIENT_MACHINE XTextProperty prop; if(XGetWMClientMachine(QX11Info::display(), w, &prop) && prop.nitems && prop.format == 8) { clientfqdn = (char *)prop.value; if(defaults::showclientmachines) { int pos = clientfqdn.indexOf('.'); if(pos == -1) clientmachine = clientfqdn; else clientmachine = clientfqdn.left(pos); } } // get WMHints get_wmhints(); // get WMNormalhints get_wmnormalhints(); int cw = init_w; int ch = init_h; getsize(&cw, &ch); // window position if(wmnflags & USPosition) { if(wmnflags & PWinGravity && (wingrav == SouthWestGravity || wingrav == SouthEastGravity)) pos_y -= uborderh; } // a transient window with program specified position looks like a dialog box, // otherwise use autoplacement else if(! defaults::start_restart && (transfor == None || ! (wmnflags & PPosition))) { if(WindowManager::next_x+cw > dt->width()) { pos_x = 0; if(cw < dt->width()) WindowManager::next_x = 2*defaults::windowbuttonsize; } else { pos_x = WindowManager::next_x; WindowManager::next_x += 2*defaults::windowbuttonsize; } int sy,ey; if(defaults::toolbar_top) { sy = defaults::tb_height; ey = dt->height(); } else { sy = 0; ey = dt->height()-defaults::tb_height; } if(WindowManager::next_y+ch > ey) { pos_y = sy; if(ch < dt->height()) WindowManager::next_y = sy+2*defaults::windowbuttonsize; } else { pos_y = WindowManager::next_y; WindowManager::next_y += 2*defaults::windowbuttonsize; } } // move and resize XResizeWindow(QX11Info::display(), clientid, cw, ch-borderh); if(pos_y < 0) pos_y = 0; setGeometry(pos_x, pos_y, cw, ch); // overwrite Qt-defaults because we need SubstructureNotifyMask XSelectInput(QX11Info::display(), winId(), KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | KeymapStateMask | ButtonMotionMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | ExposureMask | StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask); XSetWindowAttributes attr; attr.event_mask = ColormapChangeMask|PropertyChangeMask; XChangeWindowAttributes(QX11Info::display(), w, CWEventMask, &attr); // get WM protocols getwmprotocols(); // create window borders create_wborder(); // add client to lookup tables WindowManager::cwindows.insert(w, this); WindowManager::pwindows.insert(winId(), this); // get WM_NAME and set window title get_wmname(); if(shaped) reshape(); // init autofocus timer focustimer = new QTimer(this); Q_CHECK_PTR(focustimer); focustimer->setSingleShot(TRUE); connect(focustimer, SIGNAL(timeout()), SLOT(raise())); tfocustimer = new QTimer(this); // used for tiled mode Q_CHECK_PTR(tfocustimer); tfocustimer->setSingleShot(TRUE); connect(tfocustimer, SIGNAL(timeout()), SLOT(tile_maximize())); WindowManager::send_configurenotify(this); if(! urgent && ! defaults::starturgent) { setinactive(); } else { seturgent(); } if(defaults::start_restart) // restore original state { int clstate = get_clientstate(); if(clstate == IconicState) { iconify(); } else if(clstate == WithdrawnState) { withdraw(); } else map(); } else map(); #ifdef DEBUGMSG logmsg << "class xwindow constructed (WId:" << winId() << ")\n"; #endif }