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 }
mapping query_border() { if( !border ) return border = SHAPE_OFFSET(query_shape(), query_direction() ) - query_shape(); return border; }
void Frame::init() { maximized = false; set_state(1); state = "WithdrawnState"; shaped = false; XSelectInput(QX11Info::display(), winId(), KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | KeymapStateMask | ButtonMotionMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | VisibilityChangeMask | ExposureMask | StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask); XSetWindowAttributes at; at.event_mask = ColormapChangeMask|PropertyChangeMask; XChangeWindowAttributes(QX11Info::display(), c_win, CWEventMask, &at); XGrabServer(QX11Info::display()); // get the client geometry get_client_geometry(); // get the client hints get_wm_hints(); // get the client normal hints get_wm_normal_hints(); // get the client prot get_wm_protocols(); // get the client icon to show on header get_icon(); // get the client name get_wm_name(); // set the frame geometry set_frame_geometry(); // set the window modality set_window_modality(); shaped = query_shape(); if (shaped) reshape(); XSetWindowBorderWidth(QX11Info::display(), c_win, 0); //client XSetWindowBorderWidth(QX11Info::display(), winId(), 0); //frame // *** THE MOST IMPORTANT FUNCTION *** // reparent client with frame XReparentWindow(QX11Info::display(), c_win, winId(), lateral_bdr_width, top_bdr_height); qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; qDebug() << "Reparent Client:" << c_win << "with Frame:" << winId() << "- Name:" << cl_name(); qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; XAddToSaveSet(QX11Info::display(), c_win); // move and resize client XMoveResizeWindow(QX11Info::display(), c_win, lateral_bdr_width, top_bdr_height+3, client_w, client_h); //if the frame is too large, maximize it if (frame_w >= QApplication::desktop()->width()-20 || frame_h >= QApplication::desktop()->height()-40) { maximize_it(); } else // normal size { // move the frame in desktop center and resize move((QApplication::desktop()->width()/2)-(frame_w/2), (QApplication::desktop()->height()/2)-(frame_h/2)); resize(frame_w, frame_h); } qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; qDebug() << "Frame_x:" << frame_x << "Frame_y:" << frame_y << "Frame_w:" << frame_w << "Frame_h:" << frame_h; qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << "\n"; if (frame_type != "Splash") // Splash frame have no header and no border { // create frame borders/header create_borders(); // set the header pixmap set_inactive(); splash = false; } else { qDebug() << "Frame:" << winId() << "Name:" << wm_name << "is Splash type"; splash = true; } // send _NET_ACTIVE_WINDOW property Atom _net_active_window = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", False); XClientMessageEvent xev; xev.type = ClientMessage; xev.window = c_win; xev.message_type = _net_active_window; xev.format = 32; xev.data.l[0] = 1; // from application xev.data.l[1] = CurrentTime; xev.data.l[2] = 0; XSendEvent(QX11Info::display(), QApplication::desktop()->winId(), False, StructureNotifyMask, (XEvent *)&xev); // map client XMapWindow(QX11Info::display(), c_win); XSync(QX11Info::display(), false); XUngrabServer(QX11Info::display()); // show frame show(); }