예제 #1
0
void Client::manage(Boolean mapped)
{
    Boolean shouldHide, reshape;
    XWMHints *hints;
    Display *d = display();
    long mSize;
    int state;

    XSelectInput(d, m_window, ColormapChangeMask | EnterWindowMask |
		 PropertyChangeMask | FocusChangeMask);

    m_iconName = getProperty(XA_WM_ICON_NAME);
    m_name = getProperty(XA_WM_NAME);
    setLabel();

    getColormaps();
    getProtocols();
    getTransient();

    hints = XGetWMHints(d, m_window);

    if (!getState(&state)) {
	state = hints ? hints->initial_state : NormalState;
    }

    shouldHide = (state == IconicState);
    if (hints) XFree(hints);

    if (XGetWMNormalHints(d, m_window, &m_sizeHints, &mSize) == 0 ||
	m_sizeHints.flags == 0) {
	m_sizeHints.flags = PSize;
    }

    m_fixedSize = False;
//    if ((m_sizeHints.flags & (USSize | PSize))) m_fixedSize = True;
    if ((m_sizeHints.flags & (PMinSize | PMaxSize)) == (PMinSize | PMaxSize) &&
	(m_sizeHints.min_width  == m_sizeHints.max_width &&
	 m_sizeHints.min_height == m_sizeHints.max_height)) m_fixedSize = True;

    reshape = !mapped;

    if (m_fixedSize) {
	if ((m_sizeHints.flags & USPosition)) reshape = False;
	if ((m_sizeHints.flags & PPosition) && shouldHide) reshape = False;
	if ((m_transient != None)) reshape = False;
    }

    if ((m_sizeHints.flags & PBaseSize)) {
	m_minWidth  = m_sizeHints.base_width;
	m_minHeight = m_sizeHints.base_height;
    } else if ((m_sizeHints.flags & PMinSize)) {
	m_minWidth  = m_sizeHints.min_width;
	m_minHeight = m_sizeHints.min_height;
    } else {
	m_minWidth = m_minHeight = 50;
    }

    // act

    gravitate(False);

    // zeros are iffy, should be calling some Manager method
    int dw = DisplayWidth(display(), 0), dh = DisplayHeight(display(), 0);

    if (m_w < m_minWidth) {
	m_w = m_minWidth; m_fixedSize = False; reshape = True;
    }
    if (m_h < m_minHeight) {
	m_h = m_minHeight; m_fixedSize = False; reshape = True;
    }

    if (m_w > dw - 8) m_w = dw - 8;
    if (m_h > dh - 8) m_h = dh - 8;

    if (m_x > dw - m_border->xIndent()) {
	m_x = dw - m_border->xIndent();
    }

    if (m_y > dh - m_border->yIndent()) {
	m_y = dh - m_border->yIndent();
    }

    if (m_x < m_border->xIndent()) m_x = m_border->xIndent();
    if (m_y < m_border->yIndent()) m_y = m_border->yIndent();
    
    m_border->configure(m_x, m_y, m_w, m_h, 0L, Above);

    if (mapped) m_reparenting = True;
    if (reshape && !m_fixedSize) XResizeWindow(d, m_window, m_w, m_h);
    XSetWindowBorderWidth(d, m_window, 0);

    m_border->reparent();

    // (support for shaped windows absent)

    XAddToSaveSet(d, m_window);
    m_managed = True;

    if (shouldHide) hide();
    else {
	XMapWindow(d, m_window);
	m_border->map();
	setState(NormalState);

	if (CONFIG_CLICK_TO_FOCUS ||
	    (m_transient != None && activeClient() &&
	    activeClient()->m_window == m_transient)) {
	    activate();
	    mapRaised();
	} else {
	    deactivate();
	}
    }
    
    if (activeClient() && !isActive()) {
	activeClient()->installColormap();
    }

    if (CONFIG_AUTO_RAISE) {
	m_windowManager->stopConsideringFocus();
	focusIfAppropriate(False);
    }
}
예제 #2
0
파일: client.cpp 프로젝트: toby20130333/qde
void Client::init()
{
	XGrabServer(display());
	
	// reparent client with parent (qt)
	XSetWindowBorderWidth(display(), clientId, 0);  //client
	XSetWindowBorderWidth(display(), winId(), 0);  //parent
	
	XReparentWindow(display(), clientId, winId(), BORDER_WIDTH, Titlebar::getPreferedHeight(0));
	qDebug() << "CLIENT INIT - Reparent window:" << clientId << "with Qt parent:" << winId();
	
	XSetWindowAttributes at;
	at.event_mask = DECOR_EVENT_MASK;
	XChangeWindowAttributes(display(), winId(), CWEventMask, &at);
	at.event_mask = CLIENT_EVENT_MASK;
	XChangeWindowAttributes(display(), clientId, CWEventMask, &at);
	
	XAddToSaveSet(display(), clientId);
	
	XGrabButton(display(), Button1, AnyModifier, clientId, FALSE,
			ButtonPressMask|ButtonReleaseMask, 
			GrabModeSync, GrabModeAsync, None, None);
	
	// get initial client geometry
	XWindowAttributes attr;
	XGetWindowAttributes(display(), clientId, &attr);
	n_px = attr.x;
	n_py = attr.y;
	base_w = attr.width;
	base_h = attr.height;

	fixSizes();
	
	n_pw = base_w;// + DBL_BORDER_WIDTH;
	n_ph = base_h + TITLEBAR_HEIGHT + 8;
	
	getWMHints();
	getAppName();
	getWMName();
	getWMProtocols();

	windowRole = Atoms::windowType(clientId);
	
	int bx, by;
	if (windowRole == Atoms::Splash) {
		bx = by = 0;
		n_ph = n_ph - TITLEBAR_HEIGHT - 8;
	} else {
		bx = BORDER_WIDTH;
		by = TITLEBAR_HEIGHT;
	}

	XMoveResizeWindow(display(), clientId, bx, by, base_w, base_h);

	// move (in desktop center) and resize parent (qt)
	n_px = (desktop->width()-base_w)/2;
	n_py = ((desktop->height()-dock->height() - n_ph)*2)/3 + tbHeight;

	qDebug() << "desktop h = " << desktop->height() << "dock h = " << dock->height();
	qDebug() << "n_px = " << n_px << " n_py = " << n_py << " base_w = " << base_w << " base_h = " << base_h;

	move(n_px, n_py);
	resize(n_pw, n_ph);
	
	createDecor();
	
	// map client
	show();
	XMapWindow(display(), clientId);
	XSync(display(), false);
	XUngrabServer(display());
	
	maximized = false;
	// TODO: get and restore initial client state
	clientState = NormalState;
}
예제 #3
0
파일: frame.cpp 프로젝트: Fxrh/antico
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();
}
예제 #4
0
/**
@brief    Reparents the specified framed_window to a newly created frame.
@return   returns 1 if successful or 0 if no window was created.
@todo     A the moment each pointer is totally valid, in the future it will merely be an alias from another datastructure.
**/
int
create_frame(Display *display, struct Frame* frame
, Window framed_window, struct Popup_menu *window_menu, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes
, struct Cursors *cursors, struct Atoms *atoms) {
  XWindowAttributes get_attributes;

  //printf("Creating frames->list[%d] with window %lu, connection %lu\n"
  //, frames->used, (unsigned long)framed_window, (unsigned long)display);
  //add this window to the save set as soon as possible so that if an error occurs it is still available

  XAddToSaveSet(display, framed_window);
  XSync(display, False);
  XGetWindowAttributes(display, framed_window, &get_attributes);

  /*** Set up defaults ***/
  frame->focussed = False;
  frame->sticky = False;
  frame->window_name = NULL;
  frame->framed_window = framed_window;
  frame->type = unknown;
  frame->theme_type = unknown;
  frame->mode = unset;
  frame->state = none;
  frame->wants_attention = False;
  frame->transient = 0;
  frame->width_inc = 1;
  frame->height_inc = 1;
  frame->menu.item = 0;

  frame->w_inc_offset = 0;
  frame->h_inc_offset = 0;

  frame->w = get_attributes.width;
  frame->h = get_attributes.height;

  get_frame_type_and_mode (display, frame, atoms, themes);

  frame->x = get_attributes.x - themes->window_type[frame->theme_type][window].x;
  frame->y = get_attributes.y - themes->window_type[frame->theme_type][window].y;
  frame->hspace = 0 - themes->window_type[frame->theme_type][window].w;
  frame->vspace = 0 - themes->window_type[frame->theme_type][window].h;


  // This is not set to the something sensive, like the size of the workarea
  // as it may change and we can't tell if it's a default value or a real
  // one set by the client.
  // Instead, always use the MIN of the workarea dimension and these values
  frame->max_width  = INT_MAX;
  frame->max_height = INT_MAX;

  //prevent overly small windows with these sensible defaults
  frame->min_width  = MINWIDTH + frame->hspace;
  frame->min_height = MINHEIGHT + frame->vspace;

  #ifdef ALLOW_OVERSIZE_WINDOWS_WITHOUT_MINIMUM_HINTS
  Screen* screen = DefaultScreenOfDisplay(display);
  /* Ugh Horrible.  */
  /* Many apps that are resizeable ask to be the size of the screen and since windows
     often don't specifiy their minimum size, we have no other way of knowing if they
     really need to be that size or not.  In case they do, this specifies that their
     current width is their minimum size, in the hope that it is overridden by the
     size hints. This kind of behaviour causes problems on small screens like the
     eee pc. */
  if(frame->w > XWidthOfScreen(screen))  frame->min_width = frame->w;
  if(frame->h > XHeightOfScreen(screen)) frame->min_height = frame->h;
  #endif

  /* This requires hspace and vspace to be set as well as the incremental hints */
  get_frame_hints(display, frame);

  frame_type_settings(display, frame, workarea);

  //Don't manage splash screens, they just cause the workspace to be created and instantly destroyed
  if(frame->type == splash) {
    XMapWindow(display, framed_window);
    XFlush(display);
    return 0;
  }


  get_frame_state(display, frame, atoms);
  create_frame_subwindows(display, frame, themes, cursors);
  create_frame_name(display, window_menu, frame, themes, atoms);

  get_frame_wm_hints(display, frame);  //this might need to change the focus, it's mode (to hidden) and so on
  get_frame_strut_hints_as_normal_hints(display, frame, atoms);

  //_NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
  int32_t ewmh_frame_extents[4] = { themes->window_type[frame->theme_type][window].x
  , themes->window_type[frame->theme_type][window].y
  , - themes->window_type[frame->theme_type][window].x - themes->window_type[frame->theme_type][window].w
  , - themes->window_type[frame->theme_type][window].y - themes->window_type[frame->theme_type][window].h
  };

  XChangeProperty(display, framed_window, atoms->frame_extents, XA_CARDINAL
  , 32, PropModeReplace, (unsigned char *)ewmh_frame_extents, 4);

  XSetWindowBorderWidth(display, framed_window, 0);

  change_frame_mode(display, frame, unset, workarea, themes);

  #ifdef CRASH_ON_BUG
  XGrabServer(display);
  XSetErrorHandler(supress_xerror);
  #endif

  XSelectInput(display, framed_window,  0);

  //reparent the framed_window to frame->widgets[window].widget
  XReparentWindow(display, framed_window, frame->widgets[window].widget, 0, 0);
  //for some odd reason the reparent only reports an extra unmap event if the window was already unmapped
  XRaiseWindow(display, framed_window);
  XMapWindow(display, frame->widgets[window].widget);

  #ifdef CRASH_ON_BUG
  XSetErrorHandler(NULL);
  XUngrabServer(display);
  #endif

  XSelectInput(display, framed_window,  PropertyChangeMask); //Property notify is used to update titles
  XSelectInput(display, frame->widgets[window].widget
  , SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);

  //Some windows only send the destroy event (e.g., gimp splash screen)
  XSync(display, False);

  //Intercept clicks so we can set the focus and possibly raise floating windows
  XGrabButton(display, Button1, 0, frame->widgets[window].widget
  , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);

  //do it for numlock as well
  XGrabButton(display, Button1, Mod2Mask, frame->widgets[window].widget
  , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);

  frame->w += frame->hspace;
  frame->h += frame->vspace;

  check_frame_limits(display, frame, workarea, themes);

  resize_frame(display, frame, themes);
  stack_frame(display, frame, seps);
  change_frame_state(display, frame, frame->state, seps, workarea, themes, atoms);
  XMoveResizeWindow(display, framed_window, 0, 0, frame->w - frame->hspace, frame->h - frame->vspace);
  XMoveWindow(display, framed_window, 0, 0);
  XMapWindow(display, framed_window);

  XFlush(display);
  save_frame_initial_state(frame);
  return 1;
}