Ejemplo n.º 1
0
Client *Client::create(const Rect& rect, int screenNumber, const String &clazz, const String &instance, bool movable)
{
    WindowManager *wm = WindowManager::instance();
    xcb_connection_t* conn = wm->connection();
    xcb_screen_t* scr = wm->screens().at(screenNumber);

    xcb_window_t window = xcb_generate_id(conn);
    const uint32_t values[] = {
        scr->black_pixel,
        XCB_GRAVITY_NORTH_WEST,
        XCB_GRAVITY_NORTH_WEST,
        1,
        (XCB_EVENT_MASK_STRUCTURE_NOTIFY
         | XCB_EVENT_MASK_ENTER_WINDOW
         | XCB_EVENT_MASK_LEAVE_WINDOW
         | XCB_EVENT_MASK_EXPOSURE
         | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
         | XCB_EVENT_MASK_POINTER_MOTION
         | XCB_EVENT_MASK_BUTTON_PRESS
         | XCB_EVENT_MASK_BUTTON_RELEASE)
    };
    warning() << "creating client window" << rect;
    xcb_create_window(conn, XCB_COPY_FROM_PARENT, window, scr->root,
                      rect.x, rect.y, rect.width, rect.height, 0,
                      XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
                      XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | XCB_CW_WIN_GRAVITY
                      | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, values);

    xcb_icccm_wm_hints_t wmHints;
    xcb_icccm_wm_hints_set_none(&wmHints);
    xcb_icccm_wm_hints_set_input(&wmHints, 0);
    xcb_icccm_set_wm_hints(conn, window, &wmHints);

    xcb_size_hints_t wmNormalHints;
    memset(&wmNormalHints, 0, sizeof(wmNormalHints));
    xcb_icccm_size_hints_set_position(&wmNormalHints, 1, rect.x, rect.y);
    xcb_icccm_size_hints_set_size(&wmNormalHints, 1, rect.width, rect.height);
    xcb_icccm_set_wm_normal_hints(conn, window, &wmNormalHints);

    String className = clazz + ' ' + instance;
    className[clazz.size()] = '\0';
    xcb_icccm_set_wm_class(conn, window, className.size(), className.constData());
    Client *ptr = new Client(window);
    ptr->mMovable = movable;
    ptr->mRect = rect;
    ptr->mOwned = true;
    ptr->mScreenNumber = screenNumber;
    ptr->init();
    ptr->mNoFocus = true;
    Workspace *ws = wm->activeWorkspace(screenNumber);
    assert(ws);
    ptr->mWorkspace = ws;
    ws->addClient(ptr);

    wm->js().onClient(ptr);
    ptr->complete();

    sClients[window] = ptr;
    return ptr;
}
Ejemplo n.º 2
0
// === SetAsPanel() ===
void LXCB::SetAsPanel(WId win){
  if(DEBUG){ qDebug() << "XCB: SetAsPanel()"; }
  if(win==0){ return; }
  SetDisableWMActions(win); //also need to disable WM actions for this window
  //Disable Input focus (panel activation ruins task manager window detection routines)
  //  - Disable Input flag in WM_HINTS
  xcb_icccm_wm_hints_t hints;
  //qDebug() << " - Disable WM_HINTS input flag";
  xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(QX11Info::connection(), win);
  //qDebug() << " -- got cookie";
  if(1 == xcb_icccm_get_wm_hints_reply(QX11Info::connection(), cookie, &hints, NULL) ){
    //qDebug() << " -- Set no inputs flag";
     xcb_icccm_wm_hints_set_input(&hints, false); //set no input focus
     xcb_icccm_set_wm_hints(QX11Info::connection(), win, &hints); //save hints back to window
  }
  //  - Remove WM_TAKE_FOCUS from the WM_PROTOCOLS for the window
  //  - - Generate the necessary atoms
  //qDebug() << " - Generate WM_PROTOCOLS and WM_TAKE_FOCUS atoms";
  xcb_atom_t WM_PROTOCOLS, WM_TAKE_FOCUS; //the two atoms needed
  xcb_intern_atom_reply_t *preply = xcb_intern_atom_reply(QX11Info::connection(), \
			xcb_intern_atom(QX11Info::connection(), 0, 12, "WM_PROTOCOLS"), NULL);
  xcb_intern_atom_reply_t *freply = xcb_intern_atom_reply(QX11Info::connection(), \
			xcb_intern_atom(QX11Info::connection(), 0, 13, "WM_TAKE_FOCUS"), NULL); 
  bool gotatoms = false;
  if(preply && freply){
    WM_PROTOCOLS = preply->atom;
    WM_TAKE_FOCUS = freply->atom;
    free(preply);
    free(freply);
    gotatoms = true;
    //qDebug() << " -- success";
  }
  //  - - Now update the protocols for the window
  if(gotatoms){ //requires the atoms
    //qDebug() << " - Get WM_PROTOCOLS";
    xcb_icccm_get_wm_protocols_reply_t proto;
    if( 1 == xcb_icccm_get_wm_protocols_reply(QX11Info::connection(), \
			xcb_icccm_get_wm_protocols_unchecked(QX11Info::connection(), win, WM_PROTOCOLS), \
			&proto, NULL) ){
	
      //Found the current protocols, see if it has the focus atom set
			//remove the take focus atom and re-save them
      bool needremove = false;
      //Note: This first loop is required so that we can initialize the modified list with a valid size
      //qDebug() << " -- Check current protocols";
      for(unsigned int i=0; i<proto.atoms_len; i++){
        if(proto.atoms[i] == WM_TAKE_FOCUS){ needremove = true; break;}
      }
      if(needremove){
	//qDebug() << " -- Remove WM_TAKE_FOCUS protocol";
	xcb_atom_t *protolist = new xcb_atom_t[proto.atoms_len-1];
	int num = 0;
	for(unsigned int i=0; i<proto.atoms_len; i++){
	  if(proto.atoms[i] != WM_TAKE_FOCUS){
	    protolist[num] = proto.atoms[i];
	    num++;
	  }
	}
	//qDebug() << " -- Re-save modified protocols";
	xcb_icccm_set_wm_protocols(QX11Info::connection(), win, WM_PROTOCOLS, num, protolist);
      }
      //qDebug() << " -- Clear protocols reply";
      xcb_icccm_get_wm_protocols_reply_wipe(&proto);
    }//end of get protocols check
  } //end of gotatoms check
  //Make sure it has the "dock" window type
  //  - get the current window types (Not necessary, only 1 type of window needed)
  
  //  - set the adjusted window type(s)
  //qDebug() << " - Adjust window type";
  xcb_atom_t list[1]; 
    list[0] = EWMH._NET_WM_WINDOW_TYPE_DOCK;
  xcb_ewmh_set_wm_window_type(&EWMH, win, 1, list);
  
  //Make sure it is on all workspaces
  //qDebug() << " - Set window as sticky";
  SetAsSticky(win);
	
}