Пример #1
0
Workspace::Workspace() : mDamage( None ), mWaitForClients( false ), mInitialRepaint( true )
{
    Extensions::initialize();

	XGrabServer( dpy );

	// Redirect all toplevel window contents to offscreen storage
	XCompositeRedirectSubwindows( dpy, rootId(), CompositeRedirectManual );

    initClientList();

	// Request notification about toplevel window state changes
	XSelectInput( dpy, rootId(),
			SubstructureNotifyMask | ExposureMask |
			StructureNotifyMask | PropertyChangeMask );

	XUngrabServer( dpy );

	// Get the picture format for the root window
	mFormat = XRenderFindVisualFormat( dpy, visual() );

	// Create an unclipped picture for drawing on the root window
	XRenderPictureAttributes pa;
	pa.subwindow_mode = IncludeInferiors;
	mFrontbuffer = XRenderCreatePicture( dpy, rootId(), format(), CPSubwindowMode, &pa );

	createBackbuffer();

	XSync( dpy, false );
}
Пример #2
0
// Move, resize, or stacking order change
void Workspace::configureNotifyEvent( const XConfigureEvent *event )
{
	Client *client = find( event->window );

	if ( client ) {
		QRect geometry = QRect( event->x, event->y, event->width, event->height );
		int borderWidth = event->border_width;
		Window above = event->above;

		// Compress configure events. There's no need to union each of these rects with
		// the damage region, since there are only two visibly affected rects; the rect
		// where the window is currently drawn, and the rect in the last configure event,
		// which is where we'll draw the window in the next paint cycle.
		XConfigureEvent e;
		while ( XCheckTypedWindowEvent( dpy, client->winId(), ConfigureNotify, (XEvent*)&e ) )
		{
			geometry = QRect( e.x, e.y, e.width, e.height );
			borderWidth = e.border_width;
			above = e.above;
		}

		client->geometryChanged( geometry, borderWidth );
		restack( client, above );
	} else if ( event->window == rootId() ) {
		// Recreate the back buffer
		releasePicture( mBackbuffer );
		createBackbuffer();
	}
}
Пример #3
0
void Workspace::propertyNotifyEvent( const XPropertyEvent *event )
{
	//char *name = XGetAtomName( dpy, event->atom );
	//std::cout << "property \"" << name << "\" changed.\n";
	//XFree( name );


	// Handle property events for the root window
	if ( event->window == rootId() ) {
		// Major optimization when switching desktops; we'll block updates and just
		// let damage accumulate until all newly mapped windows have been painted.
		if ( event->atom == ATOM(_NET_CURRENT_DESKTOP) )
		{
			mWaitForClients = true;
			XSync( dpy, false ); // Helps to accumulate more events
		}

		// If the root window pixmap was changed
		else if ( event->atom == ATOM(_XROOTPMAP_ID) ||
		          event->atom == ATOM(_XSETROOT_ID)  ||
		          event->atom == ATOM(ESETROOT_PMAP_ID) )
		{
			// Compress these events
			XEvent dummy;
			while ( XCheckIfEvent( dpy, &dummy, rootPixmapPredicate, XPointer( rootId() ) ) );

			// Destroy the root tile picture
			releasePicture( mRootTile );

			// Damage the whole display
			XserverRegion r = createRegionFromQRect( QRect( 0, 0, width(), height() ) );
			addDamage( r );
		}
	}

	// Handle notifications of changes to window opacity hints
	else if ( event->atom == ATOM(_NET_WM_WINDOW_OPACITY))
	{
		// Compress opacity change events for the window
		XEvent dummy;
		while ( XCheckIfEvent( dpy, &dummy, windowOpacityPredicate, XPointer(event->window) ) );

		Client *client = find( event->window );
		if ( client )
			client->opacityChanged();
	}
}
Пример #4
0
void Workspace::createRootTile()
{
	Pixmap pixmap = None;

	Atom actual_type;
	int actual_format;
	ulong nitems, bytes_remaining;
	uchar *data = 0L;

	// Try to find a root window property with a pixmap ID for a background pixmap.
	Atom atoms[] = { ATOM(ESETROOT_PMAP_ID), ATOM(_XROOTPMAP_ID), ATOM(_XSETROOT_ID) };
	for (int i = 0; i < 3; i++ )
	{
		int result = XGetWindowProperty( dpy, rootId(), atoms[i], 0, 4, false, XA_PIXMAP,
						&actual_type, &actual_format, &nitems, &bytes_remaining, &data );

		if ( result == Success && actual_type == XA_PIXMAP
				   && actual_format == 32 && nitems == 1 )
		{
			pixmap = *reinterpret_cast<Pixmap*>( data );
			XFree( data );
			break;
		}
	}

	XRenderPictureAttributes pa;
	pa.repeat = true;

	// Create the root tile picture for the pixmap if one was found
	if ( pixmap != None ) {
		mRootTile = XRenderCreatePicture( dpy, pixmap, format(), CPRepeat, &pa );
	} else {
		// If no background pixmap is set, create a simply 1x1 tile
		pixmap    = XCreatePixmap( dpy, rootId(), 1, 1, depth() );
		mRootTile = XRenderCreatePicture( dpy, pixmap, format(), CPRepeat, &pa );

		// Fill it with a gray color
		XRenderColor col = { 0x8080, 0x8080, 0x8080, 0xffff };
		XRenderFillRectangle( dpy, PictOpSrc, mRootTile, &col, 0, 0, 1, 1 );
	}
}
Пример #5
0
    void SingeChildTask::load(ISerializableNode* node)
    {
        super::load(node);

        if (this->m_status != BT_INVALID)
        {
            CSerializationID  rootId("root");
            ISerializableNode* rootNode = node->findChild(rootId);
            BEHAVIAC_ASSERT(rootNode);
            this->m_root->load(rootNode);
        }
    }
Пример #6
0
// Handles expose events for the root window
void Workspace::exposeEvent( const XExposeEvent *event )
{
	if ( event->window != rootId() )
		return;

	int more = event->count + 1;
	if ( mExposeRects.count() + more > mExposeRects.capacity() )
		mExposeRects.reserve( mExposeRects.count() + more );

	XRectangle r = { event->x, event->y, event->width, event->height };
	mExposeRects.append( r );

	if ( event->count == 0 ) {
		XserverRegion damage = XFixesCreateRegion( dpy,
					&mExposeRects.first(), mExposeRects.count() );
		addDamage( damage );
		mExposeRects.clear();
	}
}
Пример #7
0
void Workspace::reparentNotifyEvent( const XReparentEvent *event )
{
	//std::cout << "got reparent event for window "
	//	<< std::hex << event->window << std::endl;

	if ( event->parent == rootId() ) {
		XWindowAttributes attr;
		if ( !XGetWindowAttributes( dpy, event->window, &attr ) )
			return;

		//std::cout << "window " << std::hex << event->window << " reparented to root\n";
		Client *client = new Client( event->window, attr );
		mList.prepend( client );
	} else {
		//std::cout << "window " << std::hex << event->window << " reparented to "
		//		<< event->parent << std::endl;
		remove( event->window );
	}
}
Пример #8
0
void Workspace::initClientList()
{
	// Get a list of all toplevel windows from the X server, sorted bottom to top
	uint nwindows;
	Window root_return, parent_return, *windows;
	XQueryTree( dpy, rootId(), &root_return,
			&parent_return, &windows, &nwindows );

	// Create a client object for each window and insert it into the window
	// list, which is sorted top to bottom. (the opposite of the order returned
	// by XQueryTree()).
	for ( uint i = 0; i < nwindows; i++ ) {
		XWindowAttributes attr;
		if ( !XGetWindowAttributes( dpy, windows[i], &attr ) )
			continue;

		mList.prepend( new Client( windows[i], attr ) );
	}

	XFree( windows );
}
Пример #9
0
void Workspace::createBackbuffer()
{
	Pixmap pixmap = XCreatePixmap( dpy, rootId(), width(), height(), depth() );
	mBackbuffer = XRenderCreatePicture( dpy, pixmap, format(), 0, 0 );
	XFreePixmap( dpy, pixmap ); // The picture owns the pixmap now
}