void LipstickCompositor::surfaceAboutToBeDestroyed(QWaylandSurface *surface) { Q_ASSERT(surface); LipstickCompositorWindow *item = static_cast<LipstickCompositorWindow *>(surface->surfaceItem()); surface->setSurfaceItem(0); if (surface == m_fullscreenSurface) setFullscreenSurface(0); if (item) { int id = item->windowId(); int gc = ghostWindowCount(); m_mappedSurfaces.remove(item->windowId()); emit windowCountChanged(); emit windowRemoved(item); item->m_windowClosed = true; item->tryRemove(); if (gc != ghostWindowCount()) emit ghostWindowCountChanged(); windowRemoved(id); emit availableWinIdsChanged(); } }
void LipstickCompositor::surfaceMapped() { QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); //Ignore surface if it's not a window surface if (!surface->hasShellSurface()) return; QVariantMap properties = surface->windowProperties(); QString category = properties.value("CATEGORY").toString(); if (surface->surfaceItem()) return; // The surface was mapped for the first time int id = m_nextWindowId++; LipstickCompositorWindow *item = new LipstickCompositorWindow(id, category, surface, contentItem()); item->setSize(surface->size()); QObject::connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed())); m_totalWindowCount++; m_mappedSurfaces.insert(id, item); item->setTouchEventsEnabled(true); emit windowCountChanged(); emit windowAdded(item); windowAdded(id); emit availableWinIdsChanged(); }
void LipstickCompositor::surfaceSizeChanged() { QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); LipstickCompositorWindow *window = static_cast<LipstickCompositorWindow *>(surface->surfaceItem()); if (window) window->setSize(surface->size()); }
// used by mapplauncherd to bring a binary to the front void WindowModel::launchProcess(const QString &binaryName) { LipstickCompositor *c = LipstickCompositor::instance(); if (!m_complete || !c) return; QStringList binaryParts = binaryName.split(QRegExp(QRegExp("\\s+"))); for (QHash<int, LipstickCompositorWindow *>::ConstIterator iter = c->m_mappedSurfaces.begin(); iter != c->m_mappedSurfaces.end(); ++iter) { LipstickCompositorWindow *win = iter.value(); if (!approveWindow(win)) continue; QString pidFile = QString::fromLatin1("/proc/%1/cmdline").arg(win->processId()); QFile f(pidFile); if (!f.open(QIODevice::ReadOnly)) { qWarning() << Q_FUNC_INFO << "Cannot open cmdline for " << pidFile; continue; } // Command line arguments are split by '\0' in /proc/*/cmdline QStringList proc; QByteArray data = f.readAll(); Q_FOREACH (const QByteArray &array, data.split('\0')) { QString part = QString::fromUtf8(array); if (part.size() > 0) { proc << part; } } // Cannot match, as the cmdline has less arguments than then binary part if (binaryParts.size() > proc.size()) { continue; } bool match = true; // All parts of binaryName must be contained in this order in the // process command line to match the given process for (int i=0; i<binaryParts.count(); i++) { if (proc[i] != binaryParts[i]) { match = false; break; } } if (match) { win->surface()->raiseRequested(); break; } } }
void LipstickCompositor::surfaceTitleChanged() { QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); LipstickCompositorWindow *window = static_cast<LipstickCompositorWindow *>(surface->surfaceItem()); if (window) { emit window->titleChanged(); int windowId = window->windowId(); for (int ii = 0; ii < m_windowModels.count(); ++ii) m_windowModels.at(ii)->titleChanged(windowId); } }
void LipstickCompositor::windowPropertyChanged(const QString &property) { QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender()); if (debug()) qDebug() << "Window properties changed:" << surface << surface->windowProperties(); if (property == QLatin1String("MOUSE_REGION")) { LipstickCompositorWindow *window = static_cast<LipstickCompositorWindow *>(surface->surfaceItem()); if (window) window->refreshMouseRegion(); } else if (property == QLatin1String("GRABBED_KEYS")) { LipstickCompositorWindow *window = static_cast<LipstickCompositorWindow *>(surface->surfaceItem()); if (window) window->refreshGrabbedKeys(); } }
QVariant WindowModel::data(const QModelIndex &index, int role) const { int idx = index.row(); if (idx < 0 || idx >= m_items.count()) return QVariant(); LipstickCompositor *c = LipstickCompositor::instance(); if (role == Qt::UserRole + 1) { return m_items.at(idx); } else if (role == Qt::UserRole + 2) { QWaylandSurface *s = c->surfaceForId(m_items.at(idx)); return s?s->processId():0; } else if (role == Qt::UserRole + 3) { LipstickCompositorWindow *w = static_cast<LipstickCompositorWindow *>(c->windowForId(m_items.at(idx))); return w->title(); } else { return QVariant(); } }
void HomeApplication::setUpdatesEnabled(bool enabled) { if (updatesEnabled != enabled) { updatesEnabled = enabled; if (!updatesEnabled) { LipstickCompositorWindow *topmostWindow = qobject_cast<LipstickCompositorWindow *>(LipstickCompositor::instance()->windowForId(LipstickCompositor::instance()->topmostWindowId())); if (topmostWindow != 0 && topmostWindow->hasFocus()) { onUpdatesDisabledUnfocusedWindowId = topmostWindow->windowId(); LipstickCompositor::instance()->clearKeyboardFocus(); } LipstickCompositor::instance()->hide(); QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("DisplayOff"); } else { QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("DisplayOn"); emit LipstickCompositor::instance()->displayAboutToBeOn(); LipstickCompositor::instance()->showFullScreen(); if (onUpdatesDisabledUnfocusedWindowId > 0) { if (!screenLock->isScreenLocked()) { LipstickCompositorWindow *topmostWindow = qobject_cast<LipstickCompositorWindow *>(LipstickCompositor::instance()->windowForId(LipstickCompositor::instance()->topmostWindowId())); if (topmostWindow != 0 && topmostWindow->windowId() == onUpdatesDisabledUnfocusedWindowId) { topmostWindow->takeFocus(); } } onUpdatesDisabledUnfocusedWindowId = 0; } } } }
QWaylandSurface *LipstickCompositor::surfaceForId(int id) const { LipstickCompositorWindow *window = m_mappedSurfaces.value(id, 0); return window?window->surface():0; }
void LipstickCompositor::closeClientForWindowId(int id) { LipstickCompositorWindow *window = m_mappedSurfaces.value(id, 0); if (window && window->surface()) destroyClientForSurface(window->surface()); }