void WMUrgentHandler::Handle (const Entity& e, const NotificationRule&)
	{
		if (e.Additional_ ["org.LC.AdvNotifications.EventCategory"].toString () == "org.LC.AdvNotifications.Cancel")
			return;

		bool ok = false;
		auto winIdx = e.Additional_ ["org.LC.AdvNotifications.WindowIndex"].toInt (&ok);

		auto rootWM = Core::Instance ().GetProxy ()->GetRootWindowsManager ();

		if (winIdx < 0 || winIdx >= rootWM->GetWindowsCount ())
		{
			qWarning () << Q_FUNC_INFO
					<< "invalid window index"
					<< winIdx
					<< "for notification"
					<< e.Additional_;
			winIdx = rootWM->GetPreferredWindowIndex ();
		}

		auto win = rootWM->GetMainWindow (ok ? winIdx : rootWM->GetPreferredWindowIndex ());

		if (!win->isActiveWindow ())
			QApplication::alert (win);
	}
	void ColorThemeEngine::SetTheme (const QString& themeName)
	{
		const auto& themePath = Loader_->GetPath (QStringList (themeName));

		if (themePath.isEmpty ())
		{
			qWarning () << Q_FUNC_INFO
					<< "no theme"
					<< themeName;
			return;
		}

		auto palette = StartupPalette_;
		if (QFile::exists (themePath + "/colors.rc"))
		{
			QSettings settings (themePath + "/colors.rc", QSettings::IniFormat);
			if (settings.childGroups ().isEmpty ())
			{
				qWarning () << Q_FUNC_INFO
						<< "error opening colors file for"
						<< themeName;
				return;
			}

			palette = UpdatePalette (StartupPalette_, settings);
		}
		QApplication::setPalette (palette);
		const auto rootWinMgr = Core::Instance ().GetRootWindowsManager ();
		for (int i = 0; i < rootWinMgr->GetWindowsCount (); ++i)
		{
			const auto win = rootWinMgr->GetMainWindow (i);
			win->setPalette (palette);

			for (auto w : win->findChildren<QWidget*> ())
				w->setPalette (palette);
		}

		QSettings qmlSettings (themePath + "/qml.rc", QSettings::IniFormat);
		FillQML (qmlSettings);

		emit themeChanged ();
	}
	bool FSWinWatcher::IsCurrentFS ()
	{
		Display *display = QX11Info::display ();
		Window focusWin;
		int reverToReturn;
		int screen = QX11Info::appScreen ();
		int screenWidth, screenHeight, width, height;
		if (!display)
			return false;

		XGetInputFocus (display, &focusWin, &reverToReturn);

		auto rootWM = Proxy_->GetRootWindowsManager ();
		for (int i = 0; i < rootWM->GetWindowsCount (); ++i)
			if (rootWM->GetMainWindow (i)->effectiveWinId () == focusWin)
				return false;

		if (!(getSize (display, RootWindow (display, screen), &screenWidth, &screenHeight) &&
				getSize (display, focusWin, &width, &height)))
			return false;

		return screenWidth == width && screenHeight == height;
	}
	QMenu* SeparateTabWidget::GetTabMenu (int index)
	{
		QMenu *menu = new QMenu ();

		const auto widget = Widget (index);
		const auto imtw = qobject_cast<ITabWidget*> (widget);

		if (XmlSettingsManager::Instance ()->
				property ("ShowPluginMenuInTabs").toBool ())
		{
			bool asSub = XmlSettingsManager::Instance ()->
				property ("ShowPluginMenuInTabsAsSubmenu").toBool ();
			if (imtw)
			{
				const auto& tabActions = imtw->GetTabBarContextMenuActions ();

				QMenu *subMenu = asSub ?
						new QMenu (TabText (index), menu) :
						nullptr;
				for (auto act : tabActions)
					(asSub ? subMenu : menu)->addAction (act);

				if (asSub)
					menu->addMenu (subMenu);

				if (tabActions.size ())
					menu->addSeparator ();
			}
		}

		auto rootWM = Core::Instance ().GetRootWindowsManager ();
		const int windowIndex = rootWM->GetWindowIndex (Window_);

		auto moveMenu = menu->addMenu (tr ("Move tab to"));
		auto toNew = moveMenu->addAction (tr ("New window"),
				rootWM, SLOT (moveTabToNewWindow ()));
		toNew->setProperty ("TabIndex", index);
		toNew->setProperty ("FromWindowIndex", windowIndex);
		if (rootWM->GetWindowsCount () > 1)
		{
			moveMenu->addSeparator ();

			for (int i = 0; i < rootWM->GetWindowsCount (); ++i)
			{
				auto thatWin = rootWM->GetMainWindow (i);
				if (thatWin == Window_)
					continue;

				const auto& actTitle = tr ("To window %1 (%2)")
							.arg (i + 1)
							.arg (thatWin->windowTitle ());
				auto toExisting = moveMenu->addAction (actTitle,
						rootWM, SLOT (moveTabToExistingWindow ()));
				toExisting->setProperty ("TabIndex", index);
				toExisting->setProperty ("FromWindowIndex", windowIndex);
				toExisting->setProperty ("ToWindowIndex", i);
			}
		}

		const auto irt = qobject_cast<IRecoverableTab*> (widget);
		if (imtw &&
				irt &&
				(imtw->GetTabClassInfo ().Features_ & TabFeature::TFOpenableByRequest) &&
				!(imtw->GetTabClassInfo ().Features_ & TabFeature::TFSingle))
		{
			const auto cloneAct = menu->addAction (tr ("Clone tab"),
					this, SLOT (handleCloneTab ()));
			cloneAct->setProperty ("TabIndex", index);
			cloneAct->setProperty ("ActionIcon", "tab-duplicate");
		}

		for (auto act : TabBarActions_)
		{
			if (!act)
			{
				qWarning () << Q_FUNC_INFO
						<< "detected null pointer";
				continue;
			}
			menu->addAction (act);
		}

		Util::DefaultHookProxy_ptr proxy (new Util::DefaultHookProxy);
		emit hookTabContextMenuFill (proxy, menu, index,
				Core::Instance ().GetRootWindowsManager ()->GetWindowIndex (Window_));

		return menu;
	}