示例#1
0
    void Spinner::initialise(void)
    {
        Window::initialise();

        // create all the component widgets
        d_increaseButton = createIncreaseButton(getName() + "__auto_incbtn__");
        addChildWindow(d_increaseButton);
        d_decreaseButton = createDecreaseButton(getName() + "__auto_decbtn__");
        addChildWindow(d_decreaseButton);
        d_editbox = createEditbox(getName() + "__auto_editbox__");
        addChildWindow(d_editbox);

        // setup component controls
        d_increaseButton->setWantsMultiClickEvents(false);
        d_increaseButton->setMouseAutoRepeatEnabled(true);
        d_decreaseButton->setWantsMultiClickEvents(false);
        d_decreaseButton->setMouseAutoRepeatEnabled(true);

        // perform event subscriptions.
        d_increaseButton->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(&Spinner::handleIncreaseButton, this));
        d_decreaseButton->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(&Spinner::handleDecreaseButton, this));
        d_editbox->subscribeEvent(Window::EventTextChanged, Event::Subscriber(&Spinner::handleEditTextChange, this));

        // final initialisation
        setTextInputMode(Integer);
        setCurrentValue(0.0f);
        performChildWindowLayout();
    }
示例#2
0
	void FalagardChatHistory::initialise(void)
	{
		// create the component sub-widgets
		d_parentWindow = static_cast<ParentWindow*>(WindowManager::getSingleton().getWindow(getName() + "__auto_parent__"));
		d_vertScrollbar = static_cast<Scrollbar*>(WindowManager::getSingleton().getWindow(getName() + "__auto_vscrollbar__"));
		d_toEnd = static_cast<PushButton*>(WindowManager::getSingleton().getWindow(getName() + "__auto_toend_btn__"));
		// alawys show.
		d_vertScrollbar->show();
		d_vertScrollbar->useSpecialThumb(true);
		
		d_parentWindow->setChatHistoryWindow(this);
		d_parentWindow->setMouseLButtonHollow(true);
		d_parentWindow->setMouseRButtonHollow(true);

		addChildWindow(d_vertScrollbar);
		addChildWindow(d_toEnd);

		//Resize child window(VerscrollBar and ParentWindow)
		performChildWindowLayout();
		//Resize all child elements.
		performWindowLayout();

		// event subscription
		d_vertScrollbar->setScrollPosition(0);
		d_vertScrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&FalagardChatHistory::handleScrollbarChange, this));
		d_toEnd->subscribeEvent(PushButton::EventMouseButtonDown, Event::Subscriber(&FalagardChatHistory::handleToEndBtnClick, this));
	}
    void ScrollablePane::initialise(void)
    {
        String widgetName;
        // create horizontal scrollbar
        widgetName = d_name + "__auto_hscrollbar__";
        d_horzScrollbar = createHorizontalScrollbar(widgetName);
        // perform consistency checks on what we got back
        assert(d_horzScrollbar != 0);
        assert(d_horzScrollbar->getName() == widgetName);

        // create vertical scrollbar
        widgetName = d_name + "__auto_vscrollbar__";
        d_vertScrollbar = createVerticalScrollbar(widgetName);
        // perform consistency checks on what we got back
        assert(d_vertScrollbar != 0);
        assert(d_vertScrollbar->getName() == widgetName);

        // create scrolled container widget
        d_container = 
            static_cast<ScrolledContainer*>(WindowManager::getSingleton().createWindow(
                ScrolledContainer::WidgetTypeName, d_name + "__auto_container__"));

        // add child controls
        addChildWindow(d_horzScrollbar);
        addChildWindow(d_vertScrollbar);
        addChildWindow(d_container);

        // do a bit of initialisation
        d_horzScrollbar->setAlwaysOnTop(true);
        d_vertScrollbar->setAlwaysOnTop(true);
        // container pane is always same size as this parent pane,
        // scrolling is actually implemented via positioning and clipping tricks.
        d_container->setSize(Relative, Size(1.0f, 1.0f));

        // subscribe to events we need to hear about
        d_vertScrollbar->subscribeEvent(
            Scrollbar::EventScrollPositionChanged,
            Event::Subscriber(&ScrollablePane::handleScrollChange, this));
        d_horzScrollbar->subscribeEvent(
            Scrollbar::EventScrollPositionChanged,
            Event::Subscriber(&ScrollablePane::handleScrollChange, this));
        d_container->subscribeEvent(
            ScrolledContainer::EventContentChanged,
            Event::Subscriber(&ScrollablePane::handleContentAreaChange, this));
        d_container->subscribeEvent(
            ScrolledContainer::EventAutoSizeSettingChanged,
            Event::Subscriber(&ScrollablePane::handleAutoSizePaneChanged, this));

        // finalise setup
        configureScrollbars();
    }
/*************************************************************************
	Initialise the Window based object ready for use.	
*************************************************************************/
void MultiLineEditbox::initialise(void)
{
	// create the component sub-widgets
	d_vertScrollbar = createVertScrollbar(getName() + "__auto_vscrollbar__");
	d_horzScrollbar = createHorzScrollbar(getName() + "__auto_hscrollbar__");

	addChildWindow(d_vertScrollbar);
	addChildWindow(d_horzScrollbar);

    d_vertScrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&MultiLineEditbox::handle_scrollChange, this));
    d_horzScrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&MultiLineEditbox::handle_scrollChange, this));

	formatText();
	performChildWindowLayout();
}
示例#5
0
/*************************************************************************
	Insert an item into the list box after a specified item already in
	the list.
*************************************************************************/
void ItemListBase::insertItem(ItemEntry* item, const ItemEntry* position)
{
    if (d_sortEnabled)
    {
        addItem(item);
    }
	else if (item && item->d_ownerList != this)
	{
		// if position is NULL begin insert at begining, else insert after item 'position'
		ItemEntryList::iterator ins_pos;

		if (!position)
		{
			ins_pos = d_listItems.begin();
		}
		else
		{
			ins_pos = std::find(d_listItems.begin(), d_listItems.end(), position);

			// throw if item 'position' is not in the list
			if (ins_pos == d_listItems.end())
			{
				throw InvalidRequestException("ItemListBase::insertItem - the specified ItemEntry for parameter 'position' is not attached to this ItemListBase.");
			}

		}

		d_listItems.insert(ins_pos, item);
		item->d_ownerList = this;
		addChildWindow(item);

		handleUpdatedItemData();
	}
}
示例#6
0
void MessageWindow::initialiseComponents()
{
   CEGUI::WindowManager& wm = CEGUI::WindowManager::getSingleton();
   setText("");

   {
      _pMessageWindow = static_cast< CEGUI::DefaultWindow* >(wm.createWindow("TaharezLook/StaticText",""));
      _pMessageWindow->setFont(::bootes::cegui::DynamicFont::GetAsciiFont(8));
      _pMessageWindow->setProperty("FrameEnabled", "false");
      addChildWindow(_pMessageWindow);
   }

   setMinSize(CEGUI::UVector2(CEGUI::UDim(0,MIN_WIDTH), CEGUI::UDim(0,MIN_HEIGHT)));
   setUpdateMode(CEGUI::WUM_VISIBLE); //default
/*
   {
      CEGUI::Size s0   = this->getParentPixelSize();
      CEGUI::Vector2 s = pChild->getMinSize().asAbsolute(s0);
      CEGUI::UDim x(0,0), y(0,0);

      x.d_offset = s.d_x + 30;
      y.d_offset = s.d_y + 60;
      this->setMinSize(CEGUI::UVector2(x,y));
      x.d_offset = (s0.d_width  - x.d_offset) / 2;
      y.d_offset = (s0.d_height - y.d_offset) / 2;
      this->setPosition(CEGUI::UVector2(x,y));
   }
*/
}
示例#7
0
bool Compositor::xcbEvent(const xcb_create_notify_event_t *e)
{
    if (e->parent != root_) {
        return false;
    }

    addChildWindow(e->window);
    return true;
}
示例#8
0
CSmallTipWnd::CSmallTipWnd()
{
	m_rcClose.SetRectEmpty ();

	m_bmpTip.LoadBitmap (IDB_TIP);
	m_bmpTip.GetBitmap (&m_bmTip);
	m_bmpClose.LoadBitmap (IDB_CLOSE);
	m_bmpClose.GetBitmap (&m_bmClose);

	addChildWindow (&m_tip);
}
示例#9
0
/*************************************************************************
	Initialises the Scrollbar object ready for use.
*************************************************************************/
void Scrollbar::initialise(void)
{
	// Set up thumb
	d_thumb = createThumb(getName() + "__auto_thumb__");
	addChildWindow(d_thumb);
	d_thumb->subscribeEvent(Thumb::EventThumbPositionChanged, Event::Subscriber(&CEGUI::Scrollbar::handleThumbMoved, this));
	d_thumb->subscribeEvent(Thumb::EventThumbTrackStarted, Event::Subscriber(&CEGUI::Scrollbar::handleThumbTrackStarted, this));
	d_thumb->subscribeEvent(Thumb::EventThumbTrackEnded, Event::Subscriber(&CEGUI::Scrollbar::handleThumbTrackEnded, this));

	// set up Increase button
	d_increase = createIncreaseButton(getName() + "__auto_incbtn__");
	addChildWindow(d_increase);
	d_increase->subscribeEvent(PushButton::EventMouseButtonDown, Event::Subscriber(&CEGUI::Scrollbar::handleIncreaseClicked, this));

	// set up Decrease button
	d_decrease = createDecreaseButton(getName() + "__auto_decbtn__");
	addChildWindow(d_decrease);
	d_decrease->subscribeEvent(PushButton::EventMouseButtonDown, Event::Subscriber(&CEGUI::Scrollbar::handleDecreaseClicked, this));

	// do initial layout
	performChildWindowLayout();
}
示例#10
0
/*************************************************************************
	Initialise the Window based object ready for use.
*************************************************************************/
void Combobox::initialise(void)
{
	d_editbox	= createEditbox(getName() + "__auto_editbox__");
	d_droplist	= createDropList(getName() + "__auto_droplist__");
	d_button	= createPushButton(getName() + "__auto_button__");
    d_droplist->setFont(getFont());
    d_editbox->setFont(getFont());

	addChildWindow(d_editbox);
	addChildWindow(d_droplist);
	addChildWindow(d_button);

	// internal event wiring
	d_button->subscribeEvent(PushButton::EventMouseButtonDown, Event::Subscriber(&CEGUI::Combobox::button_PressHandler, this));
	d_droplist->subscribeEvent(ComboDropList::EventListSelectionAccepted, Event::Subscriber(&CEGUI::Combobox::droplist_SelectionAcceptedHandler, this));
	d_droplist->subscribeEvent(Window::EventHidden, Event::Subscriber(&CEGUI::Combobox::droplist_HiddenHandler, this));
	d_editbox->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(&CEGUI::Combobox::editbox_MouseDownHandler, this));

	// event forwarding setup
	d_editbox->subscribeEvent(Editbox::EventReadOnlyModeChanged, Event::Subscriber(&CEGUI::Combobox::editbox_ReadOnlyChangedHandler, this));
	d_editbox->subscribeEvent(Editbox::EventValidationStringChanged, Event::Subscriber(&CEGUI::Combobox::editbox_ValidationStringChangedHandler, this));
	d_editbox->subscribeEvent(Editbox::EventMaximumTextLengthChanged, Event::Subscriber(&CEGUI::Combobox::editbox_MaximumTextLengthChangedHandler, this));
	d_editbox->subscribeEvent(Editbox::EventTextInvalidated, Event::Subscriber(&CEGUI::Combobox::editbox_TextInvalidatedEventHandler, this));
	d_editbox->subscribeEvent(Editbox::EventInvalidEntryAttempted, Event::Subscriber(&CEGUI::Combobox::editbox_InvalidEntryAttemptedHandler, this));
	d_editbox->subscribeEvent(Editbox::EventCaratMoved, Event::Subscriber(&CEGUI::Combobox::editbox_CaratMovedHandler, this));
	d_editbox->subscribeEvent(Editbox::EventTextSelectionChanged, Event::Subscriber(&CEGUI::Combobox::editbox_TextSelectionChangedHandler, this));
	d_editbox->subscribeEvent(Editbox::EventEditboxFull, Event::Subscriber(&CEGUI::Combobox::editbox_EditboxFullEventHandler, this));
	d_editbox->subscribeEvent(Editbox::EventTextAccepted, Event::Subscriber(&CEGUI::Combobox::editbox_TextAcceptedEventHandler, this));
	d_editbox->subscribeEvent(Editbox::EventTextChanged, Event::Subscriber(&CEGUI::Combobox::editbox_TextChangedEventHandler, this));
	d_droplist->subscribeEvent(Listbox::EventListContentsChanged, Event::Subscriber(&CEGUI::Combobox::listbox_ListContentsChangedHandler, this));
	d_droplist->subscribeEvent(Listbox::EventSelectionChanged, Event::Subscriber(&CEGUI::Combobox::listbox_ListSelectionChangedHandler, this));
	d_droplist->subscribeEvent(Listbox::EventSortModeChanged, Event::Subscriber(&CEGUI::Combobox::listbox_SortModeChangedHandler, this));
	d_droplist->subscribeEvent(Listbox::EventVertScrollbarModeChanged, Event::Subscriber(&CEGUI::Combobox::listbox_VertScrollModeChangedHandler, this));
	d_droplist->subscribeEvent(Listbox::EventHorzScrollbarModeChanged, Event::Subscriber(&CEGUI::Combobox::listbox_HorzScrollModeChangedHandler, this));

	// put components in their initial positions
	performChildWindowLayout();
}
示例#11
0
bool Compositor::xcbEvent(const xcb_reparent_notify_event_t *e)
{
    if (e->event != root_) {
        return false;
    }

    if (e->parent == root_) {
        addChildWindow(e->window);
    } else {
        removeChildWindow(e->window);
    }

    return xcbDispatchEvent(e);
}
/************************************************************************
    Initialise
************************************************************************/
void ScrolledItemListBase::initialiseComponents()
{
    // Only process the content pane if it hasn't been done in the past
    // NOTE: This ensures that a duplicate content pane is not created. An example where
    // this would be possible would be when changing the Look'N'Feel of the widget
    // (for instance an ItemListBox), an operation which would reconstruct the child components
    // of the widget by destroying the previous ones and creating new ones with the
    // new Look'N'Feel. However, since the content pane is not defined in the
    // look and feel file and thus not associated with the look'N'Feel itself
    // but instead created here manually, the destruction would not contemplate the content
    // pane itself, so when the children would be rebuilt, a duplicate content pane
    // would be attempted (and an exception would be issued).
    if(!d_pane)
    {
        // IMPORTANT:
        // we must do this before the base class handling or we'll lose the onChildRemoved subscriber!!!
        d_pane = WindowManager::getSingletonPtr()->createWindow("ClippedContainer", d_name+ContentPaneNameSuffix);

        // set up clipping
        static_cast<ClippedContainer*>(d_pane)->setClipperWindow(this);
        addChildWindow(d_pane);
    }

    // base class handling
    ItemListBase::initialiseComponents();

    // set default pane position
    Rect r = getItemRenderArea();
    d_pane->setPosition(UVector2(cegui_absdim(r.d_left),cegui_absdim(r.d_top)));

    // init scrollbars
    Scrollbar* v = getVertScrollbar();
    Scrollbar* h = getHorzScrollbar();

    v->setAlwaysOnTop(true);
    h->setAlwaysOnTop(true);

    v->subscribeEvent(Scrollbar::EventScrollPositionChanged,
        Event::Subscriber(&ScrolledItemListBase::handle_VScroll,this));
    h->subscribeEvent(Scrollbar::EventScrollPositionChanged,
        Event::Subscriber(&ScrolledItemListBase::handle_HScroll,this));

    v->hide();
    h->hide();
}
示例#13
0
	void ListBox::AddItem(const std::string& name)
	{
		if(m_font && !name.empty())
		{
			float w = m_area.getWidth() - m_borders.m_left - m_borders.m_right;
			float h = m_font->getLineSpacing();
			
			Label* st = new Label(m_system);
			st->setSize(Size(w, h));

			addChildWindow(st);
			st->setFont(m_font);
			st->setText(name);
			st->setIgnoreInputEvents(true);
			st->setAlwaysOnTop(true);
			st->setVisible(true);
		}
	}
示例#14
0
//----------------------------------------------------------------------------//
ScrollablePane::ScrollablePane(const String& type, const String& name) :
    Window(type, name),
    d_forceVertScroll(false),
    d_forceHorzScroll(false),
    d_contentRect(0, 0, 0, 0),
    d_vertStep(0.1f),
    d_vertOverlap(0.01f),
    d_horzStep(0.1f),
    d_horzOverlap(0.01f)
{
    addScrollablePaneProperties();
    
    // create scrolled container widget
    ScrolledContainer* container = static_cast<ScrolledContainer*>(
        WindowManager::getSingleton().createWindow(
            ScrolledContainer::WidgetTypeName,
            d_name + ScrolledContainerNameSuffix));

    // add scrolled container widget as child
    addChildWindow(container);
}
示例#15
0
bool MessageWindow::addButton(int id, const char* msg, int wiimote_button)
{
   CEGUI::WindowManager& wm = CEGUI::WindowManager::getSingleton();

   if (_buttons.size() == _buttons.capacity()) {
      _buttons.reserve( _buttons.capacity() * 2 );
   }
   _buttons.resize( _buttons.size() + 1 );

   ButtonEntry& e = _buttons.back();
   e.id = id;
   e.wiimote_button = wiimote_button;
//   e.wiimote_pressed = false;
   e.pButton = static_cast< ::CEGUI::PushButton* >(wm.createWindow("TaharezLook/Button", ""));
   e.pButton->setText(msg);
   e.pButton->setFont(::bootes::cegui::DynamicFont::GetAsciiFont(8));

   addChildWindow(e.pButton);
   e.pButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::SubscriberSlot(&MessageWindow::onPush, this));

   return true;
}
示例#16
0
/*************************************************************************
	Add the given ItemEntry to the list.
*************************************************************************/
void ItemListBase::addItem(ItemEntry* item)
{
    // make sure the item is valid and that we dont already have it in our list
	if (item && item->d_ownerList != this)
	{
	    // if sorting is enabled, re-sort the list
        if (d_sortEnabled)
        {
            d_listItems.insert(
                std::upper_bound(d_listItems.begin(), d_listItems.end(), item, getRealSortCallback()),
                item);
        }
        // just stick it on the end.
        else
        {
            d_listItems.push_back(item);
        }
        // make sure it gets added properly
		item->d_ownerList = this;
		addChildWindow(item);
		handleUpdatedItemData();
	}
}
void vmsSingleLineTooltip::setText(LPCTSTR ptszHtml)
{
	vmsUiStaticTextWindow tmp;
	addChildWindow (&tmp);
	tmp.setText (_T (" "), vmsUiFonts::Tahoma_11 (), RGB (0,0,0));
	CSize sSpace = tmp.getRequiredSize ();
	RemoveAllChildWindows ();

	int x = 0;

	m_sRequired.cx = 0;
	m_sRequired.cy = 0;

	bool bBold = false;
	tstring tstrLinkUrl;

	while (*ptszHtml)
	{
		if (*ptszHtml == '<')
		{
			ptszHtml++;
			tstring tstrTag;
			vmsStringParser::SkipWhiteChars (ptszHtml);
			vmsStringParser::GetWordBeforeChar (ptszHtml, '>', tstrTag);
			if (tstrTag.empty ())
				return;
			if (_tcsicmp (tstrTag.c_str (), "B") == 0)
			{
				bBold = true;
			}
			else if (_tcsicmp (tstrTag.c_str (), "/B") == 0)
			{
				bBold = false;
			}
			else if (_tcsicmp (tstrTag.c_str (), "A") == 0)
			{
				vmsStringParser::SkipWhiteChars (ptszHtml);
				tstring tstrVN, tstrVV;
				do 
				{
					vmsStringParser::GetAlphaWord (ptszHtml, tstrVN);
					if (tstrVN.empty ())
						break;
					vmsStringParser::SkipWhiteChars (ptszHtml);
					if (*ptszHtml != '=')
						continue;
					ptszHtml++;
					vmsStringParser::SkipWhiteChars (ptszHtml);
					if (*ptszHtml == '"' || *ptszHtml == '\'')
					{
						TCHAR tch = *ptszHtml++;
						vmsStringParser::GetTextBeforeChar (ptszHtml, tch, tstrVV);
						if (*ptszHtml)
							ptszHtml++;
					}
					else
					{
						vmsStringParser::GetWordBeforeChar (ptszHtml, '>', tstrVV);
					}
					
					if (_tcsicmp (tstrVN.c_str (), "href") == 0)
						tstrLinkUrl = tstrVV;

					if (*ptszHtml != '>')
						vmsStringParser::SkipWhiteChars (ptszHtml);

					if (*ptszHtml == '>')
						break;
				} 
				while (*ptszHtml);
			}
			else if (_tcsicmp (tstrTag.c_str (), "/A") == 0)
			{
				tstrLinkUrl = _T ("");
			}

			if (*ptszHtml != '>')
				vmsStringParser::GetTextBeforeChar (ptszHtml, '>', tstrTag);
			if (*ptszHtml == '>')
				ptszHtml++;

			continue;
		}

		tstring tstrText;
		vmsStringParser::GetTextBeforeChar (ptszHtml, '<', tstrText);
		vmsStringParser::RemoveNonSpaceWhiteChars (tstrText);
		if (tstrText.empty ())
			continue;

		

		if (tstrLinkUrl.empty ())
		{
			vmsUiStaticTextWindow *pText = new vmsUiStaticTextWindow;
			addChildWindow (pText);
			pText->setText (tstrText.c_str (), 
				bBold ? vmsUiFonts::Tahoma_11bold () : vmsUiFonts::Tahoma_11 (), 
				RGB (0,0,0));
			CSize s = pText->getRequiredSize ();
			pText->setPos (x, 0, s.cx, s.cy);
			x += s.cx;
			m_sRequired.cy = max (m_sRequired.cy, s.cy);
		}
		else
		{
			vmsUiLinkWindow *pLink = new vmsUiLinkWindow;
			addChildWindow (pLink);
			pLink->setLink (tstrText.c_str (), tstrLinkUrl.c_str ());
			CSize s = pLink->getSize ();
			pLink->setPos (x, 0, s.cx, s.cy);
			x += s.cx;
			m_sRequired.cy = max (m_sRequired.cy, s.cy);
		}
	}

	m_sRequired.cx = x;
}
示例#18
0
Compositor::Compositor()
    : connection_(QX11Info::connection()),
      root_(QX11Info::appRootWindow()),
      damageExt_(xcb_get_extension_data(connection_, &xcb_damage_id)),
      initFinished_(false)
{
    qRegisterMetaType<ClientWindow *>();

    Q_ASSERT(QCoreApplication::instance());
    QCoreApplication::instance()->installNativeEventFilter(this);

    auto ewmhCookie = xcb_ewmh_init_atoms(connection_, &ewmh_);
    if (!xcb_ewmh_init_atoms_replies(&ewmh_, ewmhCookie, Q_NULLPTR)) {
        qFatal("Cannot init EWMH");
    }

    auto wmCmCookie = xcb_ewmh_get_wm_cm_owner_unchecked(&ewmh_, QX11Info::appScreen());
    xcb_window_t wmCmOwnerWin = XCB_NONE;
    if (!xcb_ewmh_get_wm_cm_owner_reply(&ewmh_, wmCmCookie, &wmCmOwnerWin, Q_NULLPTR)) {
        qFatal("Cannot check _NET_WM_CM_Sn");
    }
    if (wmCmOwnerWin) {
        qFatal("Another compositing manager is already running");
    }

    auto attributesCookie = xcb_get_window_attributes_unchecked(connection_, root_);
    auto damageQueryVersionCookie = xcb_damage_query_version_unchecked(connection_, 1, 1);
    auto overlayWindowCookie = xcb_composite_get_overlay_window_unchecked(connection_, root_);

    auto attributes =
            xcbReply(xcb_get_window_attributes_reply(connection_, attributesCookie, Q_NULLPTR));
    if (!attributes) {
        qFatal("Cannot get root window attributes");
    }
    auto newEventMask = attributes->your_event_mask
            | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
            | XCB_EVENT_MASK_STRUCTURE_NOTIFY
            | XCB_EVENT_MASK_PROPERTY_CHANGE;
    xcb_change_window_attributes(connection_, root_, XCB_CW_EVENT_MASK, &newEventMask);

    auto treeCookie = xcb_query_tree_unchecked(connection_, root_);
    auto rootGeometryCookie = xcb_get_geometry_unchecked(connection_, root_);

    auto damageVersion =
            xcbReply(xcb_damage_query_version_reply(connection_, damageQueryVersionCookie, Q_NULLPTR));
    if (!damageVersion) {
        qFatal("Cannot query version of Damage extension");
    }

    auto overlayWindow =
            xcbReply(xcb_composite_get_overlay_window_reply(connection_, overlayWindowCookie, Q_NULLPTR));
    if (!overlayWindow) {
        qFatal("Cannot get overlay window");
    }
    overlayWindow_.reset(QWindow::fromWinId(overlayWindow->overlay_win));

    auto region = xcb_generate_id(connection_);
    xcb_xfixes_create_region(connection_, region, 0, Q_NULLPTR);
    xcb_xfixes_set_window_shape_region(connection_, overlayWindow->overlay_win, XCB_SHAPE_SK_INPUT, 0, 0, region);
    xcb_xfixes_destroy_region(connection_, region);

    xcb_composite_redirect_subwindows(connection_, root_, XCB_COMPOSITE_REDIRECT_MANUAL);

    auto rootGeometry =
            xcbReply(xcb_get_geometry_reply(connection_, rootGeometryCookie, Q_NULLPTR));
    if (!rootGeometry) {
        qFatal("Cannot query root window geometry");
    }
    rootGeometry_ = QRect(rootGeometry->x, rootGeometry->y, rootGeometry->width, rootGeometry->height);

    auto tree = xcbReply(xcb_query_tree_reply(connection_, treeCookie, Q_NULLPTR));
    if (!tree) {
        qFatal("Cannot query window tree");
    }

    auto children = xcb_query_tree_children(tree.get());
    for (int i = 0; i < xcb_query_tree_children_length(tree.get()); i++) {
        addChildWindow(children[i]);
    }
    updateActiveWindow();

    initFinished_ = true;
}