From ae1937badc097a864ecfc62e79e7a3899c3be572 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Fri, 6 May 2022 11:37:17 +0000 Subject: [PATCH] Remove completely present windows since it has been replaced by windowview, and Desktop Grid is ported as well, remove present windows which is effectively dead code now BUG:447001 BUG:362844 BUG:450487 BUG:453426 BUG:374481 BUG:185381 BUG:413342 BUG:451150 BUG:283333 BUG:315314 BUG:397500 BUG:321236 BUG:436572 BUG:335782 --- src/effects/CMakeLists.txt | 1 - src/effects/presentwindows/CMakeLists.txt | 45 - src/effects/presentwindows/main.cpp | 17 - src/effects/presentwindows/main.qml | 18 - src/effects/presentwindows/metadata.json | 75 - src/effects/presentwindows/presentwindows.cpp | 2054 ----------------- src/effects/presentwindows/presentwindows.h | 343 --- .../presentwindows/presentwindows.kcfg | 51 - .../presentwindows/presentwindows_config.cpp | 104 - .../presentwindows/presentwindows_config.h | 46 - .../presentwindows/presentwindows_config.ui | 487 ---- .../presentwindows/presentwindows_proxy.cpp | 36 - .../presentwindows/presentwindows_proxy.h | 35 - .../presentwindows/presentwindowsconfig.kcfgc | 6 - 14 files changed, 3318 deletions(-) delete mode 100644 src/effects/presentwindows/CMakeLists.txt delete mode 100644 src/effects/presentwindows/main.cpp delete mode 100644 src/effects/presentwindows/main.qml delete mode 100644 src/effects/presentwindows/metadata.json delete mode 100644 src/effects/presentwindows/presentwindows.cpp delete mode 100644 src/effects/presentwindows/presentwindows.h delete mode 100644 src/effects/presentwindows/presentwindows.kcfg delete mode 100644 src/effects/presentwindows/presentwindows_config.cpp delete mode 100644 src/effects/presentwindows/presentwindows_config.h delete mode 100644 src/effects/presentwindows/presentwindows_config.ui delete mode 100644 src/effects/presentwindows/presentwindows_proxy.cpp delete mode 100644 src/effects/presentwindows/presentwindows_proxy.h delete mode 100644 src/effects/presentwindows/presentwindowsconfig.kcfgc diff --git a/src/effects/CMakeLists.txt b/src/effects/CMakeLists.txt index d4d1ce996f..188ba12ff6 100644 --- a/src/effects/CMakeLists.txt +++ b/src/effects/CMakeLists.txt @@ -77,7 +77,6 @@ add_subdirectory(kscreen) add_subdirectory(screentransform) add_subdirectory(magiclamp) add_subdirectory(overview) -add_subdirectory(presentwindows) add_subdirectory(screenedge) add_subdirectory(showfps) add_subdirectory(showpaint) diff --git a/src/effects/presentwindows/CMakeLists.txt b/src/effects/presentwindows/CMakeLists.txt deleted file mode 100644 index f971688d1f..0000000000 --- a/src/effects/presentwindows/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -####################################### -# Effect -install(FILES main.qml DESTINATION ${KDE_INSTALL_DATADIR}/kwin/effects/presentwindows/) - -set(presentwindows_SOURCES - main.cpp - presentwindows.cpp - presentwindows_proxy.cpp -) - -kconfig_add_kcfg_files(presentwindows_SOURCES - presentwindowsconfig.kcfgc -) - -kwin4_add_effect_module(kwin4_effect_presentwindows ${presentwindows_SOURCES}) -target_link_libraries(kwin4_effect_presentwindows PRIVATE - kwineffects - - KF5::ConfigGui - KF5::GlobalAccel - KF5::I18n - - Qt::DBus - Qt::Qml - Qt::Quick -) - -####################################### -# Config -if (KWIN_BUILD_KCMS) - set(kwin_presentwindows_config_SRCS presentwindows_config.cpp) - ki18n_wrap_ui(kwin_presentwindows_config_SRCS presentwindows_config.ui) - kconfig_add_kcfg_files(kwin_presentwindows_config_SRCS presentwindowsconfig.kcfgc) - - kwin_add_effect_config(kwin_presentwindows_config ${kwin_presentwindows_config_SRCS}) - - target_link_libraries(kwin_presentwindows_config - KF5::ConfigWidgets - KF5::CoreAddons - KF5::GlobalAccel - KF5::I18n - KF5::XmlGui - KWinEffectsInterface - ) -endif() diff --git a/src/effects/presentwindows/main.cpp b/src/effects/presentwindows/main.cpp deleted file mode 100644 index ad85428f50..0000000000 --- a/src/effects/presentwindows/main.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - SPDX-FileCopyrightText: 2021 Vlad Zahorodnii - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#include "presentwindows.h" - -namespace KWin -{ - -KWIN_EFFECT_FACTORY(PresentWindowsEffect, - "metadata.json.stripped") - -} // namespace KWin - -#include "main.moc" diff --git a/src/effects/presentwindows/main.qml b/src/effects/presentwindows/main.qml deleted file mode 100644 index 4ae4276de3..0000000000 --- a/src/effects/presentwindows/main.qml +++ /dev/null @@ -1,18 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2013 Martin Gräßlin - - SPDX-License-Identifier: GPL-2.0-or-later -*/ -import QtQuick 2.0 -import org.kde.plasma.components 3.0 as Plasma - -Plasma.Button { - id: closeButton - icon.name: "window-close" - anchors.fill: parent - implicitWidth: units.iconSizes.medium - implicitHeight: implicitWidth -} diff --git a/src/effects/presentwindows/metadata.json b/src/effects/presentwindows/metadata.json deleted file mode 100644 index eec86c1d84..0000000000 --- a/src/effects/presentwindows/metadata.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "KPlugin": { - "Category": "Window Management", - "Description": "Zoom out until all opened windows can be displayed side-by-side", - "Description[ar]": "بعِّد إلى أن يصير بالإمكان عرض كل النوافذ المفتوحة جبناً إلى جنب", - "Description[az]": "Bütün açıq pəncərələrin miniatürünü yan-yana göstərir", - "Description[ca@valencia]": "Redueix fins que totes les finestres obertes es poden mostrar una al costat de l'atra", - "Description[ca]": "Redueix fins que totes les finestres obertes es poden mostrar una al costat de l'altra", - "Description[cs]": "Oddálí plochu, aby byla vidět všechna okna", - "Description[de]": "Verkleinert Fenster auf der Arbeitsfläche, sodass sie alle nebeneinander sichtbar sind", - "Description[en_GB]": "Zoom out until all opened windows can be displayed side-by-side", - "Description[es]": "Reducir hasta que todas las ventanas abiertas se puedan mostrar una al lado de la otra", - "Description[fi]": "Loitontaa työpöytää kunnes avoimet ikkunat voi esittää rinnakkain", - "Description[fr]": "Faire un zoom arrière jusqu'à ce que toutes les fenêtres ouvertes puissent être affichées côte à côte", - "Description[hu]": "Kinagyítja a nézetet, hogy az összes megnyitott ablak áttekinthető legyen", - "Description[ia]": "Zoom foras usque omne fenestras aperite pote esser monstrate flanco a flanco", - "Description[id]": "Zoom keluar hingga semua window yang terbuka bisa ditampilkan sisi demi sisi", - "Description[it]": "Arretra per far vedere tutte le finestre aperte fianco a fianco", - "Description[ko]": "모든 열린 창을 축소시켜서 한 화면에 보이도록 합니다", - "Description[nl]": "Zoomt uit totdat alle geopende vensters zij-aan-zij kunnen worden getoond", - "Description[nn]": "Forminsk skjermflata heilt til alle dei opne vindauga kan visast side om side", - "Description[pl]": "Pomniejsza do chwili, aż wszystkie otwarte okna będą widoczne obok siebie", - "Description[pt]": "Reduz até que todas as janelas abertas possam aparecer lado-a-lado", - "Description[pt_BR]": "Reduz até que todas as janelas abertas possam ser apresentadas lado a lado", - "Description[ro]": "Îndepărtează până toate ferestrele deschise se pot afișa una lângă alta", - "Description[ru]": "Просмотр миниатюр всех открытых окон рядом друг с другом", - "Description[sk]": "Oddiali všetky otvorené okná a zobrazí ich vedľa seba", - "Description[sl]": "Oddaljite, dokler se ne vsa odprta okna ne prikažejo eno poleg drugega", - "Description[sv]": "Zooma ut till alla öppnade fönster kan visas sida vid sida", - "Description[ta]": "அனைத்து சாளரங்களையும் பக்கத்து பக்கத்தில் சிறிதாக்கி காட்டும்", - "Description[tr]": "Tüm açık pencereler yan yana görüntülenebilene dek uzaklaştır", - "Description[uk]": "Зменшення масштабу вікон так, щоб всі відкриті вікна можна було розташувати поряд", - "Description[vi]": "Thu nhỏ cho đến khi tất cả các cửa sổ đang mở hiển thị được cạnh nhau", - "Description[x-test]": "xxZoom out until all opened windows can be displayed side-by-sidexx", - "Description[zh_CN]": "所有窗口缩小后平铺显示在一个画面上", - "EnabledByDefault": true, - "Id": "presentwindows", - "License": "GPL", - "Name": "Present Windows", - "Name[ar]": "النوافذ الحاضرة", - "Name[az]": "Hazırkı pəncərələr", - "Name[ca@valencia]": "Presenta les finestres", - "Name[ca]": "Presenta les finestres", - "Name[cs]": "Prezentace oken", - "Name[de]": "Fenster zeigen", - "Name[en_GB]": "Present Windows", - "Name[es]": "Presentar ventanas", - "Name[fi]": "Ikkunoiden esittäminen", - "Name[fr]": "Fenêtres actuelles", - "Name[hu]": "Ablakáttekintő", - "Name[ia]": "Fenestras actual", - "Name[it]": "Presenta le finestre", - "Name[ko]": "창 진열하기", - "Name[nl]": "Vensters presenteren", - "Name[nn]": "Presenter vindauge", - "Name[pl]": "Prezentacja okien", - "Name[pt]": "Apresentar as Janelas", - "Name[pt_BR]": "Apresentar janelas", - "Name[ro]": "Prezintă ferestrele", - "Name[ru]": "Все окна", - "Name[sk]": "Súčasné okná", - "Name[sl]": "Prikaži okna", - "Name[sv]": "Befintliga fönster", - "Name[ta]": "சாளரங்களை முன்வை", - "Name[tr]": "Pencereleri Sun", - "Name[uk]": "Показ вікон", - "Name[vi]": "Các cửa sổ hiện thời", - "Name[x-test]": "xxPresent Windowsxx", - "Name[zh_CN]": "窗口平铺展示" - }, - "X-KDE-ConfigModule": "kwin_presentwindows_config", - "org.kde.kwin.effect": { - "internal": true - } -} diff --git a/src/effects/presentwindows/presentwindows.cpp b/src/effects/presentwindows/presentwindows.cpp deleted file mode 100644 index e281523783..0000000000 --- a/src/effects/presentwindows/presentwindows.cpp +++ /dev/null @@ -1,2054 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2007 Rivo Laks - SPDX-FileCopyrightText: 2008 Lucas Murray - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#include "presentwindows.h" -// KConfigSkeleton -#include "presentwindowsconfig.h" -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -Q_LOGGING_CATEGORY(KWIN_PRESENTWINDOWS, "kwin_effect_presentwindows", QtWarningMsg) - -namespace KWin -{ - -PresentWindowsEffect::PresentWindowsEffect() - : m_proxy(this) - , m_activated(false) - , m_ignoreMinimized(false) - , m_decalOpacity(0.0) - , m_hasKeyboardGrab(false) - , m_mode(ModeCurrentDesktop) - , m_managerWindow(nullptr) - , m_needInitialSelection(false) - , m_highlightedWindow(nullptr) - , m_lastPresentTime(std::chrono::milliseconds::zero()) - , m_filterFrame(nullptr) - , m_closeView(nullptr) -{ - initConfig(); - - // TODO KF6 remove atom support - auto announceSupportProperties = [this] { - m_atomDesktop = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_DESKTOP", this); - m_atomWindows = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_GROUP", this); - }; - announceSupportProperties(); - connect(effects, &EffectsHandler::xcbConnectionChanged, this, announceSupportProperties); - - reconfigure(ReconfigureAll); - connect(effects, &EffectsHandler::windowAdded, this, &PresentWindowsEffect::slotWindowAdded); - connect(effects, &EffectsHandler::windowClosed, this, &PresentWindowsEffect::slotWindowClosed); - connect(effects, &EffectsHandler::windowDeleted, this, &PresentWindowsEffect::slotWindowDeleted); - connect(effects, &EffectsHandler::windowFrameGeometryChanged, this, &PresentWindowsEffect::slotWindowFrameGeometryChanged); - connect(effects, &EffectsHandler::propertyNotify, this, &PresentWindowsEffect::slotPropertyNotify); - connect(effects, &EffectsHandler::screenAdded, this, &PresentWindowsEffect::maybeRecreateGrids); - connect(effects, &EffectsHandler::screenRemoved, this, &PresentWindowsEffect::maybeRecreateGrids); - connect(effects, &EffectsHandler::screenAboutToLock, this, [this]() { - setActive(false); - }); - - QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/PresentWindows"), - QStringLiteral("org.kde.KWin.PresentWindows"), - this, - QDBusConnection::ExportScriptableSlots); - QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.KWin.PresentWindows")); -} - -PresentWindowsEffect::~PresentWindowsEffect() -{ - QDBusConnection::sessionBus().unregisterService(QStringLiteral("org.kde.KWin.PresentWindows")); - delete m_filterFrame; - delete m_closeView; -} - -void PresentWindowsEffect::reconfigure(ReconfigureFlags) -{ - PresentWindowsConfig::self()->read(); - - m_layoutMode = PresentWindowsConfig::layoutMode(); - m_showCaptions = PresentWindowsConfig::drawWindowCaptions(); - m_showIcons = PresentWindowsConfig::drawWindowIcons(); - m_doNotCloseWindows = !PresentWindowsConfig::allowClosingWindows(); - - if (m_doNotCloseWindows) { - delete m_closeView; - m_closeView = nullptr; - } - - m_ignoreMinimized = PresentWindowsConfig::ignoreMinimized(); - m_accuracy = PresentWindowsConfig::accuracy() * 20; - m_fillGaps = PresentWindowsConfig::fillGaps(); - m_fadeDuration = double(animationTime(150)); - m_showPanel = PresentWindowsConfig::showPanel(); - m_leftButtonWindow = (WindowMouseAction)PresentWindowsConfig::leftButtonWindow(); - m_middleButtonWindow = (WindowMouseAction)PresentWindowsConfig::middleButtonWindow(); - m_rightButtonWindow = (WindowMouseAction)PresentWindowsConfig::rightButtonWindow(); - m_leftButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::leftButtonDesktop(); - m_middleButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::middleButtonDesktop(); - m_rightButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::rightButtonDesktop(); -} - -void *PresentWindowsEffect::proxy() -{ - return &m_proxy; -} - -void PresentWindowsEffect::toggleActiveClass() -{ - if (!m_activated) { - if (!effects->activeWindow()) { - return; - } - m_mode = ModeWindowClass; - m_class = effects->activeWindow()->windowClass(); - } - setActive(!m_activated); -} - -//----------------------------------------------------------------------------- -// Screen painting - -void PresentWindowsEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) -{ - // The animation code assumes that the time diff cannot be 0, let's work around it. - int time; - if (m_lastPresentTime.count()) { - time = std::max(1, int((presentTime - m_lastPresentTime).count())); - } else { - time = 1; - } - m_lastPresentTime = presentTime; - - m_motionManager.calculate(time); - - // We need to mark the screen as having been transformed otherwise there will be no repainting - if (m_activated || m_motionManager.managingWindows()) { - data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - } - - if (m_activated) { - m_decalOpacity = qMin(1.0, m_decalOpacity + time / m_fadeDuration); - } else { - m_decalOpacity = qMax(0.0, m_decalOpacity - time / m_fadeDuration); - } - - effects->prePaintScreen(data, presentTime); -} - -void PresentWindowsEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) -{ - effects->paintScreen(mask, region, data); - - // Display the filter box - if (!m_windowFilter.isEmpty()) { - m_filterFrame->render(region); - } - - if (m_closeView) { - effects->renderOffscreenQuickView(m_closeView); - } -} - -void PresentWindowsEffect::postPaintScreen() -{ - if (m_motionManager.areWindowsMoving()) { - effects->addRepaintFull(); - } else { - m_lastPresentTime = std::chrono::milliseconds::zero(); - - if (!m_activated && m_motionManager.managingWindows() && !(m_closeView && m_closeView->isVisible())) { - // We have finished moving them back, stop processing - m_motionManager.unmanageAll(); - - DataHash::iterator i = m_windowData.begin(); - while (i != m_windowData.end()) { - delete i.value().textFrame; - delete i.value().iconFrame; - ++i; - } - m_windowData.clear(); - - const auto stackingOrder = effects->stackingOrder(); - for (EffectWindow *w : stackingOrder) { - w->setData(WindowForceBlurRole, QVariant()); - w->setData(WindowForceBackgroundContrastRole, QVariant()); - } - effects->setActiveFullScreenEffect(nullptr); - effects->addRepaintFull(); - } else if (m_activated && m_needInitialSelection) { - m_needInitialSelection = false; - QMouseEvent me(QEvent::MouseMove, cursorPos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); - windowInputMouseEvent(&me); - } - } - - // Update windows that are changing brightness or opacity - for (auto i = m_windowData.begin(); i != m_windowData.end(); ++i) { - bool resetLastPresentTime = true; - - if (i.value().opacity > 0.0 && i.value().opacity < 1.0) { - i.key()->addRepaintFull(); - resetLastPresentTime = false; - } - if (i.key()->isDesktop() && !m_motionManager.isManaging(i.key())) { - if (i.value().highlight != 0.3) { - i.key()->addRepaintFull(); - resetLastPresentTime = false; - } - } else if (i.value().highlight > 0.0 && i.value().highlight < 1.0) { - i.key()->addRepaintFull(); - resetLastPresentTime = false; - } - - if (resetLastPresentTime) { - i->lastPresentTime = std::chrono::milliseconds::zero(); - } - } - - effects->postPaintScreen(); -} - -//----------------------------------------------------------------------------- -// Window painting - -void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) -{ - // TODO: We should also check to see if any windows are fading just in case fading takes longer - // than moving the windows when the effect is deactivated. - if (m_activated || m_motionManager.areWindowsMoving() || m_closeView) { - DataHash::iterator winData = m_windowData.find(w); - if (winData == m_windowData.end()) { - effects->prePaintWindow(w, data, presentTime); - return; - } - - // The animation code assumes that the time diff cannot be 0, let's work around it. - int time; - if (winData->lastPresentTime.count()) { - time = std::max(1, int((presentTime - winData->lastPresentTime).count())); - } else { - time = 1; - } - winData->lastPresentTime = presentTime; - - // Calculate window's opacity - // TODO: Minimized windows or windows not on the current desktop are only 75% visible? - if (winData->visible) { - if (winData->deleted) { - winData->opacity = qMax(0.0, winData->opacity - time / m_fadeDuration); - } else { - winData->opacity = qMin(/*(w->isMinimized() || !w->isOnCurrentDesktop()) ? 0.75 :*/ 1.0, - winData->opacity + time / m_fadeDuration); - } - } else { - winData->opacity = qMax(0.0, winData->opacity - time / m_fadeDuration); - } - - const bool isInMotion = m_motionManager.isManaging(w); - // Calculate window's brightness - if (w == m_highlightedWindow || !m_activated) { - winData->highlight = qMin(1.0, winData->highlight + time / m_fadeDuration); - } else if (!isInMotion && w->isDesktop()) { - winData->highlight = 0.3; - } else { - winData->highlight = qMax(0.0, winData->highlight - time / m_fadeDuration); - } - - // Closed windows - if (winData->deleted) { - data.setTranslucent(); - if (winData->opacity <= 0.0 && !winData->deletedRef.isNull()) { - // it's possible that another effect has referenced the window - // we have to keep the window in the list to prevent flickering - winData->deletedRef = EffectWindowDeletedRef{}; - } - } - - if (isInMotion) { - data.setTransformed(); // We will be moving this window - } - if (winData->opacity != 1.0) { - data.setTranslucent(); - } - } - effects->prePaintWindow(w, data, presentTime); -} - -void PresentWindowsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) -{ - if (m_activated || m_motionManager.areWindowsMoving()) { - // desktop windows on other desktops (Plasma activity per desktop) should not be painted - if (w->isDesktop() && !w->isOnCurrentDesktop()) { - return; - } - - DataHash::const_iterator winData = m_windowData.constFind(w); - if (winData == m_windowData.constEnd() || (w->isDock() && m_showPanel)) { - // we are darkening the panel to communicate that it's not interactive - data.multiplyBrightness(interpolate(0.40, 1.0, winData->highlight)); - effects->paintWindow(w, mask, region, data); - return; - } - - mask |= PAINT_WINDOW_LANCZOS; - // Apply opacity and brightness - data.multiplyOpacity(winData->opacity); - data.multiplyBrightness(interpolate(0.40, 1.0, winData->highlight)); - - if (m_motionManager.isManaging(w)) { - if (w->isDesktop()) { - effects->paintWindow(w, mask, region, data); - } - m_motionManager.apply(w, data); - QRect rect = m_motionManager.transformedGeometry(w).toRect(); - - if (m_activated && winData->highlight > 0.0) { - // scale the window (interpolated by the highlight level) to at least 105% or to cover 1/16 of the screen size - yet keep it in screen bounds - QRect area = effects->clientArea(FullScreenArea, w); - - QSizeF effSize(w->width() * data.xScale(), w->height() * data.yScale()); - const float xr = area.width() / effSize.width(); - const float yr = area.height() / effSize.height(); - float tScale = 0.0; - if (xr < yr) { - tScale = qMax(xr / 4.0, yr / 32.0); - } else { - tScale = qMax(xr / 32.0, yr / 4.0); - } - if (tScale < 1.05) { - tScale = 1.05; - } - if (effSize.width() * tScale > area.width()) { - tScale = area.width() / effSize.width(); - } - if (effSize.height() * tScale > area.height()) { - tScale = area.height() / effSize.height(); - } - - const qreal scale = interpolate(1.0, tScale, winData->highlight); - if (scale > 1.0) { - if (scale < tScale) { // don't use lanczos during transition - mask &= ~PAINT_WINDOW_LANCZOS; - } - - const float df = (tScale - 1.0f) * 0.5f; - int tx = qRound(rect.width() * df); - int ty = qRound(rect.height() * df); - QRect tRect(rect.adjusted(-tx, -ty, tx, ty)); - tx = qMax(tRect.x(), area.x()) + qMin(0, area.right() - tRect.right()); - ty = qMax(tRect.y(), area.y()) + qMin(0, area.bottom() - tRect.bottom()); - tx = qRound((tx - rect.x()) * winData->highlight); - ty = qRound((ty - rect.y()) * winData->highlight); - - rect.translate(tx, ty); - rect.setWidth(rect.width() * scale); - rect.setHeight(rect.height() * scale); - - data *= QVector2D(scale, scale); - data += QPoint(tx, ty); - } - } - - if (m_motionManager.areWindowsMoving()) { - mask &= ~PAINT_WINDOW_LANCZOS; - } - effects->paintWindow(w, mask, region, data); - - if (m_showIcons) { - QPoint point(rect.x() + rect.width() / 2, - rect.y() + rect.height() / 2); - winData->iconFrame->setAlignment(Qt::AlignCenter); - winData->iconFrame->setPosition(point); - if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) { - const float a = 0.9 * data.opacity() * m_decalOpacity * 0.75; - data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a)); - } - winData->iconFrame->render(region, 0.9 * data.opacity() * m_decalOpacity, 0.75); - } - if (m_showCaptions) { - QSize iconSize = winData->iconFrame->iconSize(); - QPoint point(rect.x() + rect.width() / 2, - rect.y() + rect.height() / 2 + iconSize.height()); - winData->textFrame->setPosition(point); - if (effects->compositingType() == KWin::OpenGLCompositing && data.shader) { - const float a = 0.9 * data.opacity() * m_decalOpacity * 0.75; - data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a)); - } - winData->textFrame->render(region, 0.9 * data.opacity() * m_decalOpacity, 0.75); - } - } else { - effects->paintWindow(w, mask, region, data); - } - } else { - effects->paintWindow(w, mask, region, data); - } -} - -//----------------------------------------------------------------------------- -// User interaction - -void PresentWindowsEffect::slotWindowAdded(EffectWindow *w) -{ - if (!m_activated) { - return; - } - - WindowData *winData = &m_windowData[w]; - winData->visible = isVisibleWindow(w); - winData->opacity = 0.0; - winData->highlight = 0.0; - winData->textFrame = effects->effectFrame(EffectFrameUnstyled, false); - - QFont font; - font.setBold(true); - font.setPointSize(12); - - winData->textFrame->setFont(font); - winData->iconFrame = effects->effectFrame(EffectFrameUnstyled, false); - winData->iconFrame->setAlignment(Qt::AlignCenter); - winData->iconFrame->setIcon(w->icon()); - winData->iconFrame->setIconSize(QSize(64, 64)); - - if (isSelectableWindow(w)) { - m_motionManager.manage(w); - rearrangeWindows(); - } -} - -void PresentWindowsEffect::slotWindowClosed(EffectWindow *w) -{ - if (m_managerWindow == w) { - m_managerWindow = nullptr; - } - - DataHash::iterator winData = m_windowData.find(w); - if (winData == m_windowData.end()) { - return; - } - - winData->deleted = true; - winData->deletedRef = EffectWindowDeletedRef(w); - - if (m_highlightedWindow == w) { - setHighlightedWindow(findFirstWindow()); - } - - rearrangeWindows(); - - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *w : managedWindows) { - winData = m_windowData.find(w); - if (winData != m_windowData.end() && !winData->deleted) { - return; // found one that is not deleted? then we go on - } - } - setActive(false); // else no need to keep this open -} - -void PresentWindowsEffect::slotWindowDeleted(EffectWindow *w) -{ - DataHash::iterator winData = m_windowData.find(w); - if (winData == m_windowData.end()) { - return; - } - - delete winData->textFrame; - delete winData->iconFrame; - m_windowData.erase(winData); - m_motionManager.unmanage(w); -} - -void PresentWindowsEffect::slotWindowFrameGeometryChanged(EffectWindow *w, const QRect &old) -{ - Q_UNUSED(old) - - if (!m_activated) { - return; - } - if (!m_windowData.contains(w)) { - return; - } - - rearrangeWindows(); -} - -void PresentWindowsEffect::windowInputMouseEvent(QEvent *e) -{ - QMouseEvent *me = dynamic_cast(e); - if (!me) { - return; - } - me->setAccepted(false); - - if (m_closeView) { - const bool contains = m_closeView->geometry().contains(me->pos()); - if (!m_closeView->isVisible() && contains) { - updateCloseWindow(); - } - m_closeView->forwardMouseEvent(e); - } - if (e->isAccepted()) { - return; - } - inputEventUpdate(me->pos(), me->type(), me->button()); -} - -void PresentWindowsEffect::inputEventUpdate(const QPoint &pos, QEvent::Type type, Qt::MouseButton button) -{ - // Which window are we hovering over? Always trigger as we don't always get move events before clicking - // We cannot use m_motionManager.windowAtPoint() as the window might not be visible - EffectWindowList windows = m_motionManager.managedWindows(); - bool hovering = false; - EffectWindow *highlightCandidate = nullptr; - for (int i = 0; i < windows.size(); ++i) { - DataHash::const_iterator winData = m_windowData.constFind(windows.at(i)); - if (winData == m_windowData.constEnd()) { - continue; - } - - if (m_motionManager.transformedGeometry(windows.at(i)).contains(pos) && winData->visible && !winData->deleted) { - hovering = true; - if (windows.at(i) && m_highlightedWindow != windows.at(i)) { - highlightCandidate = windows.at(i); - } - break; - } - } - - if (!hovering) { - if (m_windowFilter.isEmpty()) { - setHighlightedWindow(nullptr); - } - } - if (m_highlightedWindow && m_motionManager.transformedGeometry(m_highlightedWindow).contains(pos)) { - updateCloseWindow(); - } else if (m_closeView) { - m_closeView->hide(); - } - - if (type == QEvent::MouseButtonRelease) { - if (highlightCandidate) { - setHighlightedWindow(highlightCandidate); - } - if (button == Qt::LeftButton) { - if (hovering) { - // mouse is hovering above a window - use MouseActionsWindow - mouseActionWindow(m_leftButtonWindow); - } else { - // mouse is hovering above desktop - use MouseActionsDesktop - mouseActionDesktop(m_leftButtonDesktop); - } - } - if (button == Qt::MiddleButton) { - if (hovering) { - // mouse is hovering above a window - use MouseActionsWindow - mouseActionWindow(m_middleButtonWindow); - } else { - // mouse is hovering above desktop - use MouseActionsDesktop - mouseActionDesktop(m_middleButtonDesktop); - } - } - if (button == Qt::RightButton) { - if (hovering) { - // mouse is hovering above a window - use MouseActionsWindow - mouseActionWindow(m_rightButtonWindow); - } else { - // mouse is hovering above desktop - use MouseActionsDesktop - mouseActionDesktop(m_rightButtonDesktop); - } - } - } else if (highlightCandidate && !m_motionManager.areWindowsMoving() && m_windowFilter.isEmpty()) { - setHighlightedWindow(highlightCandidate); - } -} - -bool PresentWindowsEffect::touchDown(qint32 id, const QPointF &pos, quint32 time) -{ - Q_UNUSED(time) - - if (!m_activated) { - return false; - } - - // only if we don't track a touch id yet - if (!m_touch.active) { - m_touch.active = true; - m_touch.id = id; - inputEventUpdate(pos.toPoint()); - } - return true; -} - -bool PresentWindowsEffect::touchMotion(qint32 id, const QPointF &pos, quint32 time) -{ - Q_UNUSED(id) - Q_UNUSED(time) - - if (!m_activated) { - return false; - } - if (m_touch.active && m_touch.id == id) { - // only update for the touch id we track - inputEventUpdate(pos.toPoint()); - } - return true; -} - -bool PresentWindowsEffect::touchUp(qint32 id, quint32 time) -{ - Q_UNUSED(id) - Q_UNUSED(time) - - if (!m_activated) { - return false; - } - if (m_touch.active && m_touch.id == id) { - m_touch.active = false; - m_touch.id = 0; - if (m_highlightedWindow) { - mouseActionWindow(m_leftButtonWindow); - } - } - return true; -} - -void PresentWindowsEffect::mouseActionWindow(WindowMouseAction &action) -{ - switch (action) { - case WindowActivateAction: - if (m_highlightedWindow) { - effects->activateWindow(m_highlightedWindow); - } - setActive(false); - break; - case WindowExitAction: - setActive(false); - break; - case WindowToCurrentDesktopAction: - if (m_highlightedWindow) { - effects->windowToDesktop(m_highlightedWindow, effects->currentDesktop()); - } - break; - case WindowToAllDesktopsAction: - if (m_highlightedWindow) { - if (m_highlightedWindow->isOnAllDesktops()) { - effects->windowToDesktop(m_highlightedWindow, effects->currentDesktop()); - } else { - effects->windowToDesktop(m_highlightedWindow, NET::OnAllDesktops); - } - } - break; - case WindowMinimizeAction: - if (m_highlightedWindow) { - if (m_highlightedWindow->isMinimized()) { - m_highlightedWindow->unminimize(); - } else { - m_highlightedWindow->minimize(); - } - } - break; - case WindowCloseAction: - if (m_highlightedWindow) { - m_highlightedWindow->closeWindow(); - } - break; - default: - break; - } -} - -void PresentWindowsEffect::mouseActionDesktop(DesktopMouseAction &action) -{ - switch (action) { - case DesktopActivateAction: - if (m_highlightedWindow) { - effects->activateWindow(m_highlightedWindow); - } - setActive(false); - break; - case DesktopExitAction: - setActive(false); - break; - case DesktopShowDesktopAction: - effects->setShowingDesktop(true); - setActive(false); - default: - break; - } -} - -void PresentWindowsEffect::grabbedKeyboardEvent(QKeyEvent *e) -{ - if (e->type() == QEvent::KeyPress) { - switch (e->key()) { - // Wrap only if not auto-repeating - case Qt::Key_Left: - setHighlightedWindow(relativeWindow(m_highlightedWindow, -1, 0, !e->isAutoRepeat())); - break; - case Qt::Key_Right: - setHighlightedWindow(relativeWindow(m_highlightedWindow, 1, 0, !e->isAutoRepeat())); - break; - case Qt::Key_Up: - setHighlightedWindow(relativeWindow(m_highlightedWindow, 0, -1, !e->isAutoRepeat())); - break; - case Qt::Key_Down: - setHighlightedWindow(relativeWindow(m_highlightedWindow, 0, 1, !e->isAutoRepeat())); - break; - case Qt::Key_Home: - setHighlightedWindow(relativeWindow(m_highlightedWindow, -1000, 0, false)); - break; - case Qt::Key_End: - setHighlightedWindow(relativeWindow(m_highlightedWindow, 1000, 0, false)); - break; - case Qt::Key_PageUp: - setHighlightedWindow(relativeWindow(m_highlightedWindow, 0, -1000, false)); - break; - case Qt::Key_PageDown: - setHighlightedWindow(relativeWindow(m_highlightedWindow, 0, 1000, false)); - break; - case Qt::Key_Backspace: - if (!m_windowFilter.isEmpty()) { - m_windowFilter.remove(m_windowFilter.length() - 1, 1); - updateFilterFrame(); - rearrangeWindows(); - } - return; - case Qt::Key_Escape: - setActive(false); - return; - case Qt::Key_Return: - case Qt::Key_Enter: - if (m_highlightedWindow) { - effects->activateWindow(m_highlightedWindow); - } - setActive(false); - return; - case Qt::Key_Tab: - return; // Nothing at the moment - case Qt::Key_Delete: - if (!m_windowFilter.isEmpty()) { - m_windowFilter.clear(); - updateFilterFrame(); - rearrangeWindows(); - } - break; - case 0: - return; // HACK: Workaround for Qt bug on unbound keys (#178547) - default: - if (!e->text().isEmpty()) { - setHighlightedWindow(nullptr); - m_windowFilter.append(e->text()); - updateFilterFrame(); - rearrangeWindows(); - return; - } - break; - } - } -} - -//----------------------------------------------------------------------------- -// Atom handling -void PresentWindowsEffect::slotPropertyNotify(EffectWindow *w, long a) -{ - if (m_atomDesktop == XCB_ATOM_NONE && m_atomWindows == XCB_ATOM_NONE) { - return; - } - if (!w || (a != m_atomDesktop && a != m_atomWindows)) { - return; // Not our atom - } - - if (a == m_atomDesktop) { - QByteArray byteData = w->readProperty(m_atomDesktop, m_atomDesktop, 32); - if (byteData.length() < 1) { - // Property was removed, end present windows - setActive(false); - return; - } - auto *data = reinterpret_cast(byteData.data()); - - if (!data[0]) { - // Purposely ending present windows by issuing a NULL target - setActive(false); - return; - } - // present windows is active so don't do anything - if (m_activated) { - return; - } - - int desktop = data[0]; - if (desktop > effects->numberOfDesktops()) { - return; - } - if (desktop == -1) { - toggleActiveAllDesktops(); - } else { - m_mode = ModeSelectedDesktop; - m_desktop = desktop; - m_managerWindow = w; - setActive(true); - } - } else if (a == m_atomWindows) { - QByteArray byteData = w->readProperty(m_atomWindows, m_atomWindows, 32); - if (byteData.length() < 1) { - // Property was removed, end present windows - setActive(false); - return; - } - auto *data = reinterpret_cast(byteData.data()); - - if (!data[0]) { - // Purposely ending present windows by issuing a NULL target - setActive(false); - return; - } - // present windows is active so don't do anything - if (m_activated) { - return; - } - - // for security clear selected windows - m_selectedWindows.clear(); - int length = byteData.length() / sizeof(data[0]); - for (int i = 0; i < length; i++) { - EffectWindow *foundWin = effects->findWindow(data[i]); - if (!foundWin) { - qCDebug(KWIN_PRESENTWINDOWS) << "Invalid window targetted for present windows. Requested:" << data[i]; - continue; - } - m_selectedWindows.append(foundWin); - } - m_mode = ModeWindowGroup; - m_managerWindow = w; - setActive(true); - } -} - -void PresentWindowsEffect::presentWindows(const QStringList &windows) -{ - m_selectedWindows.clear(); - for (const auto &window : windows) { - if (auto effectWindow = effects->findWindow(QUuid(window)); effectWindow) { - m_selectedWindows.append(effectWindow); - } else if (auto effectWindow = effects->findWindow(window.toLong()); effectWindow) { - m_selectedWindows.append(effectWindow); - } - } - m_mode = ModeWindowGroup; - setActive(true); -} - -//----------------------------------------------------------------------------- -// Window rearranging - -void PresentWindowsEffect::rearrangeWindows() -{ - if (!m_activated) { - return; - } - - effects->addRepaintFull(); // Trigger the first repaint - if (m_closeView) { - m_closeView->hide(); - } - - // Work out which windows are on which screens - EffectWindowList windowlist; - QMap windowlists; - - if (m_windowFilter.isEmpty()) { - windowlist = m_motionManager.managedWindows(); - for (EffectWindow *w : qAsConst(windowlist)) { - DataHash::iterator winData = m_windowData.find(w); - if (winData == m_windowData.end() || winData->deleted) { - continue; // don't include closed windows - } - windowlists[w->screen()].append(w); - winData->visible = true; - } - } else { - // Can we move this filtering somewhere else? - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *w : managedWindows) { - DataHash::iterator winData = m_windowData.find(w); - if (winData == m_windowData.end() || winData->deleted) { - continue; // don't include closed windows - } - - if (w->caption().contains(m_windowFilter, Qt::CaseInsensitive) || w->windowClass().contains(m_windowFilter, Qt::CaseInsensitive) || w->windowRole().contains(m_windowFilter, Qt::CaseInsensitive)) { - windowlist.append(w); - windowlists[w->screen()].append(w); - winData->visible = true; - } else { - winData->visible = false; - } - } - } - if (windowlist.isEmpty()) { - setHighlightedWindow(nullptr); - return; - } - - // We filtered out the highlighted window - if (m_highlightedWindow) { - DataHash::iterator winData = m_windowData.find(m_highlightedWindow); - if (winData != m_windowData.end() && !winData->visible) { - setHighlightedWindow(findFirstWindow()); - } - } else { - setHighlightedWindow(findFirstWindow()); - } - - const QList screens = effects->screens(); - for (EffectScreen *screen : screens) { - EffectWindowList windows; - windows = windowlists[screen]; - - // Don't rearrange if the grid is the same size as what it was before to prevent - // windows moving to a better spot if one was filtered out. - if (m_layoutMode == LayoutRegularGrid && m_gridSizes[screen].columns && m_gridSizes[screen].rows && windows.size() < m_gridSizes[screen].columns * m_gridSizes[screen].rows && windows.size() > (m_gridSizes[screen].columns - 1) * m_gridSizes[screen].rows && windows.size() > m_gridSizes[screen].columns * (m_gridSizes[screen].rows - 1)) { - continue; - } - - // No point continuing if there is no windows to process - if (!windows.count()) { - continue; - } - - calculateWindowTransformations(windows, screen, m_motionManager); - } - - // Resize text frames if required - QFontMetrics *metrics = nullptr; // All fonts are the same - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *w : managedWindows) { - DataHash::iterator winData = m_windowData.find(w); - if (winData == m_windowData.end()) { - continue; - } - - if (!metrics) { - metrics = new QFontMetrics(winData->textFrame->font()); - } - - QRect geom = m_motionManager.targetGeometry(w).toRect(); - QString string = metrics->elidedText(w->caption(), Qt::ElideRight, geom.width() * 0.9); - if (string != winData->textFrame->text()) { - winData->textFrame->setText(string); - } - } - delete metrics; -} - -void PresentWindowsEffect::calculateWindowTransformations(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager, bool external) -{ - if (m_layoutMode == LayoutRegularGrid) { - calculateWindowTransformationsClosest(windowlist, screen, motionManager); - } else if (m_layoutMode == LayoutFlexibleGrid) { - calculateWindowTransformationsKompose(windowlist, screen, motionManager); - } else { - calculateWindowTransformationsNatural(windowlist, screen, motionManager); - } - - // If called externally we don't need to remember this data - if (external) { - m_windowData.clear(); - } -} - -static inline int distance(QPoint &pos1, QPoint &pos2) -{ - const int xdiff = pos1.x() - pos2.x(); - const int ydiff = pos1.y() - pos2.y(); - return int(sqrt(float(xdiff * xdiff + ydiff * ydiff))); -} - -void PresentWindowsEffect::calculateWindowTransformationsClosest(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager) -{ - // This layout mode requires at least one window visible - if (windowlist.count() == 0) { - return; - } - - QRect area = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); - if (m_showPanel) { // reserve space for the panel - area = effects->clientArea(MaximizeArea, screen, effects->currentDesktop()); - } - int columns = int(ceil(sqrt(double(windowlist.count())))); - int rows = int(ceil(windowlist.count() / double(columns))); - - // Remember the size for later - // If we are using this layout externally we don't need to remember m_gridSizes. - if (m_gridSizes.size() != 0) { - m_gridSizes[screen].columns = columns; - m_gridSizes[screen].rows = rows; - } - - // Assign slots - int slotWidth = area.width() / columns; - int slotHeight = area.height() / rows; - QVector takenSlots; - takenSlots.resize(rows * columns); - takenSlots.fill(0); - - // precalculate all slot centers - QVector slotCenters; - slotCenters.resize(rows * columns); - for (int x = 0; x < columns; ++x) { - for (int y = 0; y < rows; ++y) { - slotCenters[x + y * columns] = QPoint(area.x() + slotWidth * x + slotWidth / 2, - area.y() + slotHeight * y + slotHeight / 2); - } - } - - // Assign each window to the closest available slot - EffectWindowList tmpList = windowlist; // use a QLinkedList copy instead? - QPoint otherPos; - while (!tmpList.isEmpty()) { - EffectWindow *w = tmpList.first(); - int slotCandidate = -1, slotCandidateDistance = INT_MAX; - QPoint pos = w->frameGeometry().center(); - - for (int i = 0; i < columns * rows; ++i) { // all slots - const int dist = distance(pos, slotCenters[i]); - if (dist < slotCandidateDistance) { // window is interested in this slot - EffectWindow *occupier = takenSlots[i]; - Q_ASSERT(occupier != w); - if (!occupier || dist < distance((otherPos = occupier->frameGeometry().center()), slotCenters[i])) { - // either nobody lives here, or we're better - takeover the slot if it's our best - slotCandidate = i; - slotCandidateDistance = dist; - } - } - } - Q_ASSERT(slotCandidate != -1); - if (takenSlots[slotCandidate]) { - tmpList << takenSlots[slotCandidate]; // occupier needs a new home now :p - } - tmpList.removeAll(w); - takenSlots[slotCandidate] = w; // ...and we rumble in =) - } - - for (int slot = 0; slot < columns * rows; ++slot) { - EffectWindow *w = takenSlots[slot]; - if (!w) { // some slots might be empty - continue; - } - - // Work out where the slot is - QRect target( - area.x() + (slot % columns) * slotWidth, - area.y() + (slot / columns) * slotHeight, - slotWidth, slotHeight); - target.adjust(10, 10, -10, -10); // Borders - - double scale; - if (target.width() / double(w->width()) < target.height() / double(w->height())) { - // Center vertically - scale = target.width() / double(w->width()); - target.moveTop(target.top() + (target.height() - int(w->height() * scale)) / 2); - target.setHeight(int(w->height() * scale)); - } else { - // Center horizontally - scale = target.height() / double(w->height()); - target.moveLeft(target.left() + (target.width() - int(w->width() * scale)) / 2); - target.setWidth(int(w->width() * scale)); - } - // Don't scale the windows too much - if (scale > 2.0 || (scale > 1.0 && (w->width() > 300 || w->height() > 300))) { - scale = (w->width() > 300 || w->height() > 300) ? 1.0 : 2.0; - target = QRect( - target.center().x() - int(w->width() * scale) / 2, - target.center().y() - int(w->height() * scale) / 2, - scale * w->width(), scale * w->height()); - } - motionManager.moveWindow(w, target); - } -} - -void PresentWindowsEffect::calculateWindowTransformationsKompose(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager) -{ - // This layout mode requires at least one window visible - if (windowlist.count() == 0) { - return; - } - - QRect availRect = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); - if (m_showPanel) { // reserve space for the panel - availRect = effects->clientArea(MaximizeArea, screen, effects->currentDesktop()); - } - std::sort(windowlist.begin(), windowlist.end()); // The location of the windows should not depend on the stacking order - - // Following code is taken from Kompose 0.5.4, src/komposelayout.cpp - int spacing = 10; - int rows, columns; - double parentRatio = availRect.width() / (double)availRect.height(); - // Use more columns than rows when parent's width > parent's height - if (parentRatio > 1) { - columns = (int)ceil(sqrt((double)windowlist.count())); - rows = (int)ceil((double)windowlist.count() / (double)columns); - } else { - rows = (int)ceil(sqrt((double)windowlist.count())); - columns = (int)ceil((double)windowlist.count() / (double)rows); - } - // qCDebug(KWIN_PRESENTWINDOWS) << "Using " << rows << " rows & " << columns << " columns for " << windowlist.count() << " clients"; - - // Calculate width & height - int w = (availRect.width() - (columns + 1) * spacing) / columns; - int h = (availRect.height() - (rows + 1) * spacing) / rows; - - EffectWindowList::iterator it(windowlist.begin()); - QList geometryRects; - QList maxRowHeights; - // Process rows - for (int i = 0; i < rows; ++i) { - int xOffsetFromLastCol = 0; - int maxHeightInRow = 0; - // Process columns - for (int j = 0; j < columns; ++j) { - EffectWindow *window; - - // Check for end of List - if (it == windowlist.end()) { - break; - } - window = *it; - - // Calculate width and height of widget - double ratio = aspectRatio(window); - - int widgetw = 100; - int widgeth = 100; - int usableW = w; - int usableH = h; - - // use width of two boxes if there is no right neighbour - if (window == windowlist.last() && j != columns - 1) { - usableW = 2 * w; - } - ++it; // We need access to the neighbour in the following - // expand if right neighbour has ratio < 1 - if (j != columns - 1 && it != windowlist.end() && aspectRatio(*it) < 1) { - int addW = w - widthForHeight(*it, h); - if (addW > 0) { - usableW = w + addW; - } - } - - if (ratio == -1) { - widgetw = w; - widgeth = h; - } else { - double widthByHeight = widthForHeight(window, usableH); - double heightByWidth = heightForWidth(window, usableW); - if ((ratio >= 1.0 && heightByWidth <= usableH) || (ratio < 1.0 && widthByHeight > usableW)) { - widgetw = usableW; - widgeth = (int)heightByWidth; - } else if ((ratio < 1.0 && widthByHeight <= usableW) || (ratio >= 1.0 && heightByWidth > usableH)) { - widgeth = usableH; - widgetw = (int)widthByHeight; - } - // Don't upscale large-ish windows - if (widgetw > window->width() && (window->width() > 300 || window->height() > 300)) { - widgetw = window->width(); - widgeth = window->height(); - } - } - - // Set the Widget's size - - int alignmentXoffset = 0; - int alignmentYoffset = 0; - if (i == 0 && h > widgeth) { - alignmentYoffset = h - widgeth; - } - if (j == 0 && w > widgetw) { - alignmentXoffset = w - widgetw; - } - QRect geom(availRect.x() + j * (w + spacing) + spacing + alignmentXoffset + xOffsetFromLastCol, - availRect.y() + i * (h + spacing) + spacing + alignmentYoffset, - widgetw, widgeth); - geometryRects.append(geom); - - // Set the x offset for the next column - if (alignmentXoffset == 0) { - xOffsetFromLastCol += widgetw - w; - } - if (maxHeightInRow < widgeth) { - maxHeightInRow = widgeth; - } - } - maxRowHeights.append(maxHeightInRow); - } - - int topOffset = 0; - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - int pos = i * columns + j; - if (pos >= windowlist.count()) { - break; - } - - EffectWindow *window = windowlist[pos]; - QRect target = geometryRects[pos]; - target.setY(target.y() + topOffset); - // @Marrtin: any idea what this is good for? - // DataHash::iterator winData = m_windowData.find(window); - // if (winData != m_windowData.end()) - // winData->slot = pos; - motionManager.moveWindow(window, target); - - // qCDebug(KWIN_PRESENTWINDOWS) << "Window '" << window->caption() << "' gets moved to (" << - // mWindowData[window].area.left() << "; " << mWindowData[window].area.right() << - // "), scale: " << mWindowData[window].scale << endl; - } - if (maxRowHeights[i] - h > 0) { - topOffset += maxRowHeights[i] - h; - } - } -} - -void PresentWindowsEffect::calculateWindowTransformationsNatural(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager) -{ - // If windows do not overlap they scale into nothingness, fix by resetting. To reproduce - // just have a single window on a Xinerama screen or have two windows that do not touch. - // TODO: Work out why this happens, is most likely a bug in the manager. - for (EffectWindow *w : qAsConst(windowlist)) { - if (motionManager.transformedGeometry(w) == w->frameGeometry()) { - motionManager.reset(w); - } - } - - if (windowlist.count() == 1) { - // Just move the window to its original location to save time - if (effects->clientArea(FullScreenArea, windowlist[0]).contains(windowlist[0]->frameGeometry())) { - motionManager.moveWindow(windowlist[0], windowlist[0]->frameGeometry()); - return; - } - } - - // As we are using pseudo-random movement (See "slot") we need to make sure the list - // is always sorted the same way no matter which window is currently active. - std::sort(windowlist.begin(), windowlist.end()); - - QRect area = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); - if (m_showPanel) { // reserve space for the panel - area = effects->clientArea(MaximizeArea, screen, effects->currentDesktop()); - } - QRect bounds = area; - int direction = 0; - QHash targets; - QHash directions; - for (EffectWindow *w : qAsConst(windowlist)) { - bounds = bounds.united(w->frameGeometry()); - targets[w] = w->frameGeometry(); - // Reuse the unused "slot" as a preferred direction attribute. This is used when the window - // is on the edge of the screen to try to use as much screen real estate as possible. - directions[w] = direction; - direction++; - if (direction == 4) { - direction = 0; - } - } - - // Iterate over all windows, if two overlap push them apart _slightly_ as we try to - // brute-force the most optimal positions over many iterations. - bool overlap; - do { - overlap = false; - for (EffectWindow *w : qAsConst(windowlist)) { - QRect *target_w = &targets[w]; - for (EffectWindow *e : qAsConst(windowlist)) { - if (w == e) { - continue; - } - - QRect *target_e = &targets[e]; - if (target_w->adjusted(-5, -5, 5, 5).intersects(target_e->adjusted(-5, -5, 5, 5))) { - overlap = true; - - // Determine pushing direction - QPoint diff(target_e->center() - target_w->center()); - // Prevent dividing by zero and non-movement - if (diff.x() == 0 && diff.y() == 0) { - diff.setX(1); - } - // Try to keep screen aspect ratio - // if (bounds.height() / bounds.width() > area.height() / area.width()) - // diff.setY(diff.y() / 2); - // else - // diff.setX(diff.x() / 2); - // Approximate a vector of between 10px and 20px in magnitude in the same direction - diff *= m_accuracy / double(diff.manhattanLength()); - // Move both windows apart - target_w->translate(-diff); - target_e->translate(diff); - - // Try to keep the bounding rect the same aspect as the screen so that more - // screen real estate is utilised. We do this by splitting the screen into nine - // equal sections, if the window center is in any of the corner sections pull the - // window towards the outer corner. If it is in any of the other edge sections - // alternate between each corner on that edge. We don't want to determine it - // randomly as it will not produce consistant locations when using the filter. - // Only move one window so we don't cause large amounts of unnecessary zooming - // in some situations. We need to do this even when expanding later just in case - // all windows are the same size. - // (We are using an old bounding rect for this, hopefully it doesn't matter) - int xSection = (target_w->x() - bounds.x()) / (bounds.width() / 3); - int ySection = (target_w->y() - bounds.y()) / (bounds.height() / 3); - diff = QPoint(0, 0); - if (xSection != 1 || ySection != 1) { // Remove this if you want the center to pull as well - if (xSection == 1) { - xSection = (directions[w] / 2 ? 2 : 0); - } - if (ySection == 1) { - ySection = (directions[w] % 2 ? 2 : 0); - } - } - if (xSection == 0 && ySection == 0) { - diff = QPoint(bounds.topLeft() - target_w->center()); - } - if (xSection == 2 && ySection == 0) { - diff = QPoint(bounds.topRight() - target_w->center()); - } - if (xSection == 2 && ySection == 2) { - diff = QPoint(bounds.bottomRight() - target_w->center()); - } - if (xSection == 0 && ySection == 2) { - diff = QPoint(bounds.bottomLeft() - target_w->center()); - } - if (diff.x() != 0 || diff.y() != 0) { - diff *= m_accuracy / double(diff.manhattanLength()); - target_w->translate(diff); - } - - // Update bounding rect - bounds = bounds.united(*target_w); - bounds = bounds.united(*target_e); - } - } - } - } while (overlap); - - // Work out scaling by getting the most top-left and most bottom-right window coords. - // The 20's and 10's are so that the windows don't touch the edge of the screen. - double scale; - if (bounds == area) { - scale = 1.0; // Don't add borders to the screen - } else if (area.width() / double(bounds.width()) < area.height() / double(bounds.height())) { - scale = (area.width() - 20) / double(bounds.width()); - } else { - scale = (area.height() - 20) / double(bounds.height()); - } - // Make bounding rect fill the screen size for later steps - bounds = QRect( - (bounds.x() * scale - (area.width() - 20 - bounds.width() * scale) / 2 - 10) / scale, - (bounds.y() * scale - (area.height() - 20 - bounds.height() * scale) / 2 - 10) / scale, - area.width() / scale, - area.height() / scale); - - // Move all windows back onto the screen and set their scale - QHash::iterator target = targets.begin(); - while (target != targets.end()) { - target->setRect((target->x() - bounds.x()) * scale + area.x(), - (target->y() - bounds.y()) * scale + area.y(), - target->width() * scale, - target->height() * scale); - ++target; - } - - // Try to fill the gaps by enlarging windows if they have the space - if (m_fillGaps) { - // Don't expand onto or over the border - QRegion borderRegion(area.adjusted(-200, -200, 200, 200)); - borderRegion ^= area.adjusted(10 / scale, 10 / scale, -10 / scale, -10 / scale); - - bool moved; - do { - moved = false; - for (EffectWindow *w : qAsConst(windowlist)) { - QRect oldRect; - QRect *target = &targets[w]; - // This may cause some slight distortion if the windows are enlarged a large amount - int widthDiff = m_accuracy; - int heightDiff = heightForWidth(w, target->width() + widthDiff) - target->height(); - int xDiff = widthDiff / 2; // Also move a bit in the direction of the enlarge, allows the - int yDiff = heightDiff / 2; // center windows to be enlarged if there is gaps on the side. - - // heightDiff (and yDiff) will be re-computed after each successful enlargement attempt - // so that the error introduced in the window's aspect ratio is minimized - - // Attempt enlarging to the top-right - oldRect = *target; - target->setRect(target->x() + xDiff, - target->y() - yDiff - heightDiff, - target->width() + widthDiff, - target->height() + heightDiff); - if (isOverlappingAny(w, targets, borderRegion)) { - *target = oldRect; - } else { - moved = true; - heightDiff = heightForWidth(w, target->width() + widthDiff) - target->height(); - yDiff = heightDiff / 2; - } - - // Attempt enlarging to the bottom-right - oldRect = *target; - target->setRect( - target->x() + xDiff, - target->y() + yDiff, - target->width() + widthDiff, - target->height() + heightDiff); - if (isOverlappingAny(w, targets, borderRegion)) { - *target = oldRect; - } else { - moved = true; - heightDiff = heightForWidth(w, target->width() + widthDiff) - target->height(); - yDiff = heightDiff / 2; - } - - // Attempt enlarging to the bottom-left - oldRect = *target; - target->setRect( - target->x() - xDiff - widthDiff, - target->y() + yDiff, - target->width() + widthDiff, - target->height() + heightDiff); - if (isOverlappingAny(w, targets, borderRegion)) { - *target = oldRect; - } else { - moved = true; - heightDiff = heightForWidth(w, target->width() + widthDiff) - target->height(); - yDiff = heightDiff / 2; - } - - // Attempt enlarging to the top-left - oldRect = *target; - target->setRect( - target->x() - xDiff - widthDiff, - target->y() - yDiff - heightDiff, - target->width() + widthDiff, - target->height() + heightDiff); - if (isOverlappingAny(w, targets, borderRegion)) { - *target = oldRect; - } else { - moved = true; - } - } - } while (moved); - - // The expanding code above can actually enlarge windows over 1.0/2.0 scale, we don't like this - // We can't add this to the loop above as it would cause a never-ending loop so we have to make - // do with the less-than-optimal space usage with using this method. - for (EffectWindow *w : qAsConst(windowlist)) { - QRect *target = &targets[w]; - double scale = target->width() / double(w->width()); - if (scale > 2.0 || (scale > 1.0 && (w->width() > 300 || w->height() > 300))) { - scale = (w->width() > 300 || w->height() > 300) ? 1.0 : 2.0; - target->setRect( - target->center().x() - int(w->width() * scale) / 2, - target->center().y() - int(w->height() * scale) / 2, - w->width() * scale, - w->height() * scale); - } - } - } - - // Notify the motion manager of the targets - for (EffectWindow *w : qAsConst(windowlist)) { - motionManager.moveWindow(w, targets.value(w)); - } -} - -bool PresentWindowsEffect::isOverlappingAny(EffectWindow *w, const QHash &targets, const QRegion &border) -{ - QHash::const_iterator winTarget = targets.find(w); - if (winTarget == targets.constEnd()) { - return false; - } - if (border.intersects(*winTarget)) { - return true; - } - - // Is there a better way to do this? - QHash::const_iterator target; - for (target = targets.constBegin(); target != targets.constEnd(); ++target) { - if (target == winTarget) { - continue; - } - if (winTarget->adjusted(-5, -5, 5, 5).intersects(target->adjusted(-5, -5, 5, 5))) { - return true; - } - } - return false; -} - -//----------------------------------------------------------------------------- -// Activation - -void PresentWindowsEffect::setActive(bool active) -{ - if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this) { - return; - } - if (m_activated == active) { - return; - } - if (effects->isScreenLocked() && active) { - return; - } - - m_activated = active; - if (m_activated) { - effects->setShowingDesktop(false); - m_needInitialSelection = true; - m_closeButtonCorner = (Qt::Corner)effects->kwinOption(KWin::CloseButtonCorner).toInt(); - m_decalOpacity = 0.0; - m_highlightedWindow = nullptr; - m_windowFilter.clear(); - - if (!(m_doNotCloseWindows || m_closeView)) { - m_closeView = new CloseWindowView(); - connect(m_closeView, &OffscreenQuickView::repaintNeeded, this, []() { - effects->addRepaintFull(); - }); - connect(m_closeView, &CloseWindowView::requestClose, this, &PresentWindowsEffect::closeWindow); - } - - // Add every single window to m_windowData (Just calling [w] creates it) - const auto stackingOrder = effects->stackingOrder(); - for (EffectWindow *w : stackingOrder) { - DataHash::iterator winData; - if ((winData = m_windowData.find(w)) != m_windowData.end()) { - winData->visible = isVisibleWindow(w); - continue; // Happens if we reactivate before the ending animation finishes - } - - winData = m_windowData.insert(w, WindowData()); - winData->visible = isVisibleWindow(w); - winData->deleted = false; - winData->opacity = 0.0; - if (w->isOnCurrentDesktop() && !w->isMinimized()) { - winData->opacity = 1.0; - } - - winData->visibleRef = EffectWindowVisibleRef(w, EffectWindow::PAINT_DISABLED_BY_DESKTOP | EffectWindow::PAINT_DISABLED_BY_MINIMIZE); - - winData->highlight = 1.0; - winData->textFrame = effects->effectFrame(EffectFrameUnstyled, false); - - QFont font; - font.setBold(true); - font.setPointSize(12); - - winData->textFrame->setFont(font); - winData->iconFrame = effects->effectFrame(EffectFrameUnstyled, false); - winData->iconFrame->setAlignment(Qt::AlignCenter); - winData->iconFrame->setIcon(w->icon()); - winData->iconFrame->setIconSize(QSize(64, 64)); - } - - // Filter out special windows such as panels and taskbars - for (EffectWindow *w : stackingOrder) { - if (isSelectableWindow(w)) { - m_motionManager.manage(w); - } - } - - if (m_motionManager.managedWindows().isEmpty()) { - // No point triggering if there is nothing to do - m_activated = false; - - DataHash::iterator i = m_windowData.begin(); - while (i != m_windowData.end()) { - delete i.value().textFrame; - delete i.value().iconFrame; - ++i; - } - m_windowData.clear(); - - m_motionManager.unmanageAll(); - return; - } - - // Create temporary input window to catch mouse events - effects->startMouseInterception(this, Qt::ArrowCursor); - m_hasKeyboardGrab = effects->grabKeyboard(this); - effects->setActiveFullScreenEffect(this); - - reCreateGrids(); - rearrangeWindows(); - setHighlightedWindow(effects->activeWindow()); - - for (EffectWindow *w : stackingOrder) { - w->setData(WindowForceBlurRole, QVariant(true)); - w->setData(WindowForceBackgroundContrastRole, QVariant(true)); - } - } else { - m_needInitialSelection = false; - if (m_highlightedWindow) { - effects->setElevatedWindow(m_highlightedWindow, false); - } - - // Fade in/out all windows - EffectWindow *activeWindow = effects->activeWindow(); - int desktop = effects->currentDesktop(); - if (activeWindow && !activeWindow->isOnAllDesktops()) { - desktop = activeWindow->desktop(); - } - const auto stackingOrder = effects->stackingOrder(); - for (EffectWindow *w : stackingOrder) { - DataHash::iterator winData = m_windowData.find(w); - if (winData != m_windowData.end()) { - winData->visible = (w->isOnDesktop(desktop) || w->isOnAllDesktops()) && !w->isMinimized(); - } - } - if (m_closeView) { - m_closeView->hide(); - } - - // Move all windows back to their original position - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *w : managedWindows) { - m_motionManager.moveWindow(w, w->frameGeometry()); - } - if (m_filterFrame) { - m_filterFrame->free(); - } - m_windowFilter.clear(); - m_selectedWindows.clear(); - - effects->stopMouseInterception(this); - if (m_hasKeyboardGrab) { - effects->ungrabKeyboard(); - } - m_hasKeyboardGrab = false; - - // destroy atom on manager window - if (m_managerWindow) { - if (m_mode == ModeSelectedDesktop && m_atomDesktop != XCB_ATOM_NONE) { - m_managerWindow->deleteProperty(m_atomDesktop); - } else if (m_mode == ModeWindowGroup && m_atomWindows != XCB_ATOM_NONE) { - m_managerWindow->deleteProperty(m_atomWindows); - } - m_managerWindow = nullptr; - } - } - - effects->addRepaintFull(); // Trigger the first repaint -} - -//----------------------------------------------------------------------------- -// Filter box - -void PresentWindowsEffect::updateFilterFrame() -{ - QRect area = effects->clientArea(ScreenArea, effects->activeScreen(), effects->currentDesktop()); - if (!m_filterFrame) { - m_filterFrame = effects->effectFrame(EffectFrameStyled, false); - QFont font; - font.setPointSize(font.pointSize() * 2); - font.setBold(true); - m_filterFrame->setFont(font); - } - m_filterFrame->setPosition(QPoint(area.x() + area.width() / 2, area.y() + area.height() / 10)); - m_filterFrame->setText(m_windowFilter); -} - -//----------------------------------------------------------------------------- -// Helper functions - -bool PresentWindowsEffect::isSelectableWindow(EffectWindow *w) -{ - if (!w->isOnCurrentActivity()) { - return false; - } - if (w->isSpecialWindow() || w->isUtility()) { - return false; - } - if (w->isDeleted()) { - return false; - } - if (!w->acceptsFocus()) { - return false; - } - if (w->isSkipSwitcher()) { - return false; - } - if (m_ignoreMinimized && w->isMinimized()) { - return false; - } - - switch (m_mode) { - default: - case ModeAllDesktops: - return true; - case ModeCurrentDesktop: - return w->isOnCurrentDesktop(); - case ModeSelectedDesktop: - return w->isOnDesktop(m_desktop); - case ModeWindowGroup: - return m_selectedWindows.contains(w); - case ModeWindowClass: - return m_class == w->windowClass(); - } -} - -bool PresentWindowsEffect::isVisibleWindow(EffectWindow *w) -{ - if (w->isDesktop()) { - return true; - } - return isSelectableWindow(w); -} - -void PresentWindowsEffect::setHighlightedWindow(EffectWindow *w) -{ - if (w == m_highlightedWindow || (w != nullptr && !m_motionManager.isManaging(w))) { - return; - } - - if (m_closeView) { - m_closeView->hide(); - } - if (m_highlightedWindow) { - effects->setElevatedWindow(m_highlightedWindow, false); - m_highlightedWindow->addRepaintFull(); // Trigger the first repaint - } - m_highlightedWindow = w; - if (m_highlightedWindow) { - effects->setElevatedWindow(m_highlightedWindow, true); - m_highlightedWindow->addRepaintFull(); // Trigger the first repaint - } - - updateCloseWindow(); -} - -void PresentWindowsEffect::updateCloseWindow() -{ - if (!m_closeView || m_doNotCloseWindows) { - return; - } - - if (!m_activated || !m_highlightedWindow || m_highlightedWindow->isDesktop()) { - m_closeView->hide(); - return; - } - if (m_closeView->isVisible()) { - return; - } - - const QRectF rect(m_motionManager.targetGeometry(m_highlightedWindow)); - if (2 * m_closeView->geometry().width() > rect.width() && 2 * m_closeView->geometry().height() > rect.height()) { - // not for tiny windows (eg. with many windows) - they might become unselectable - m_closeView->hide(); - return; - } - - QRect cvr(QPoint(0, 0), m_closeView->size()); - switch (m_closeButtonCorner) { - case Qt::TopLeftCorner: - default: - cvr.moveTopLeft(rect.topLeft().toPoint()); - break; - case Qt::TopRightCorner: - cvr.moveTopRight(rect.topRight().toPoint()); - break; - case Qt::BottomLeftCorner: - cvr.moveBottomLeft(rect.bottomLeft().toPoint()); - break; - case Qt::BottomRightCorner: - cvr.moveBottomRight(rect.bottomRight().toPoint()); - break; - } - - m_closeView->setGeometry(cvr); - - if (rect.contains(effects->cursorPos())) { - m_closeView->show(); - m_closeView->disarm(); - } else { - m_closeView->hide(); - } -} - -void PresentWindowsEffect::closeWindow() -{ - if (m_highlightedWindow) { - m_highlightedWindow->closeWindow(); - } -} - -EffectWindow *PresentWindowsEffect::relativeWindow(EffectWindow *w, int xdiff, int ydiff, bool wrap) const -{ - if (!w) { - return m_motionManager.managedWindows().constFirst(); - } - - // TODO: Is it possible to select hidden windows? - EffectWindow *next; - QRect area = effects->virtualScreenGeometry(); - QRect detectRect; - - // Detect across the width of the desktop - if (xdiff != 0) { - if (xdiff > 0) { - // Detect right - for (int i = 0; i < xdiff; i++) { - QRectF wArea = m_motionManager.transformedGeometry(w); - detectRect = QRect(0, wArea.y(), area.width(), wArea.height()); - next = nullptr; - - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *e : managedWindows) { - DataHash::const_iterator winData = m_windowData.find(e); - if (winData == m_windowData.end() || !winData->visible) { - continue; - } - - QRectF eArea = m_motionManager.transformedGeometry(e); - if (eArea.intersects(detectRect) && eArea.x() > wArea.x()) { - if (next == nullptr) { - next = e; - } else { - QRectF nArea = m_motionManager.transformedGeometry(next); - if (eArea.x() < nArea.x()) { - next = e; - } - } - } - } - if (next == nullptr) { - if (wrap) { // We are at the right-most window, now get the left-most one to wrap - return relativeWindow(w, -1000, 0, false); - } - break; // No more windows to the right - } - w = next; - } - return w; - } else { - // Detect left - for (int i = 0; i < -xdiff; i++) { - QRectF wArea = m_motionManager.transformedGeometry(w); - detectRect = QRect(0, wArea.y(), area.width(), wArea.height()); - next = nullptr; - - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *e : managedWindows) { - DataHash::const_iterator winData = m_windowData.find(e); - if (winData == m_windowData.end() || !winData->visible) { - continue; - } - - QRectF eArea = m_motionManager.transformedGeometry(e); - if (eArea.intersects(detectRect) && eArea.x() + eArea.width() < wArea.x() + wArea.width()) { - if (next == nullptr) { - next = e; - } else { - QRectF nArea = m_motionManager.transformedGeometry(next); - if (eArea.x() + eArea.width() > nArea.x() + nArea.width()) { - next = e; - } - } - } - } - if (next == nullptr) { - if (wrap) { // We are at the left-most window, now get the right-most one to wrap - return relativeWindow(w, 1000, 0, false); - } - break; // No more windows to the left - } - w = next; - } - return w; - } - } - - // Detect across the height of the desktop - if (ydiff != 0) { - if (ydiff > 0) { - // Detect down - for (int i = 0; i < ydiff; i++) { - QRectF wArea = m_motionManager.transformedGeometry(w); - detectRect = QRect(wArea.x(), 0, wArea.width(), area.height()); - next = nullptr; - - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *e : managedWindows) { - DataHash::const_iterator winData = m_windowData.find(e); - if (winData == m_windowData.end() || !winData->visible) { - continue; - } - - QRectF eArea = m_motionManager.transformedGeometry(e); - if (eArea.intersects(detectRect) && eArea.y() > wArea.y()) { - if (next == nullptr) { - next = e; - } else { - QRectF nArea = m_motionManager.transformedGeometry(next); - if (eArea.y() < nArea.y()) { - next = e; - } - } - } - } - if (next == nullptr) { - if (wrap) { // We are at the bottom-most window, now get the top-most one to wrap - return relativeWindow(w, 0, -1000, false); - } - break; // No more windows to the bottom - } - w = next; - } - return w; - } else { - // Detect up - for (int i = 0; i < -ydiff; i++) { - QRectF wArea = m_motionManager.transformedGeometry(w); - detectRect = QRect(wArea.x(), 0, wArea.width(), area.height()); - next = nullptr; - - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *e : managedWindows) { - DataHash::const_iterator winData = m_windowData.find(e); - if (winData == m_windowData.end() || !winData->visible) { - continue; - } - - QRectF eArea = m_motionManager.transformedGeometry(e); - if (eArea.intersects(detectRect) && eArea.y() + eArea.height() < wArea.y() + wArea.height()) { - if (next == nullptr) { - next = e; - } else { - QRectF nArea = m_motionManager.transformedGeometry(next); - if (eArea.y() + eArea.height() > nArea.y() + nArea.height()) { - next = e; - } - } - } - } - if (next == nullptr) { - if (wrap) { // We are at the top-most window, now get the bottom-most one to wrap - return relativeWindow(w, 0, 1000, false); - } - break; // No more windows to the top - } - w = next; - } - return w; - } - } - - Q_UNREACHABLE(); // Should never get here -} - -EffectWindow *PresentWindowsEffect::findFirstWindow() const -{ - EffectWindow *topLeft = nullptr; - QRectF topLeftGeometry; - - const auto managedWindows = m_motionManager.managedWindows(); - for (EffectWindow *w : managedWindows) { - DataHash::const_iterator winData = m_windowData.find(w); - if (winData == m_windowData.end()) { - continue; - } - QRectF geometry = m_motionManager.transformedGeometry(w); - if (winData->visible == false) { - continue; // Not visible - } - if (winData->deleted) { - continue; // Window has been closed - } - if (topLeft == nullptr) { - topLeft = w; - topLeftGeometry = geometry; - } else if (geometry.x() < topLeftGeometry.x() || geometry.y() < topLeftGeometry.y()) { - topLeft = w; - topLeftGeometry = geometry; - } - } - return topLeft; -} - -bool PresentWindowsEffect::isActive() const -{ - return (m_activated || m_motionManager.managingWindows()) && !effects->isScreenLocked(); -} - -void PresentWindowsEffect::maybeRecreateGrids() -{ - if (isActive()) { - reCreateGrids(); - } -} - -void PresentWindowsEffect::reCreateGrids() -{ - m_gridSizes.clear(); - const QList screens = effects->screens(); - for (EffectScreen *screen : screens) { - m_gridSizes.insert(screen, GridSize()); - } - rearrangeWindows(); -} - -CloseWindowView::CloseWindowView(QObject *parent) - : OffscreenQuickScene(parent) -{ - setSource(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/presentwindows/main.qml")))); - if (QQuickItem *item = rootItem()) { - connect(item, SIGNAL(clicked()), this, SLOT(clicked())); - setGeometry(QRect(QPoint(), QSize(item->implicitWidth(), item->implicitHeight()))); - } - m_armTimer.restart(); -} - -void CloseWindowView::clicked() -{ - // 50ms until the window is elevated (seen!) and 300ms more to be "realized" by the user. - if (m_armTimer.hasExpired(350)) { - Q_EMIT requestClose(); - } -} - -void CloseWindowView::disarm() -{ - m_armTimer.restart(); -} - -} // namespace diff --git a/src/effects/presentwindows/presentwindows.h b/src/effects/presentwindows/presentwindows.h deleted file mode 100644 index 37769273d2..0000000000 --- a/src/effects/presentwindows/presentwindows.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2007 Rivo Laks - SPDX-FileCopyrightText: 2008 Lucas Murray - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#ifndef KWIN_PRESENTWINDOWS_H -#define KWIN_PRESENTWINDOWS_H - -#include "presentwindows_proxy.h" - -#include -#include - -#include - -class QMouseEvent; -class QQuickView; - -namespace KWin -{ -class CloseWindowView : public OffscreenQuickScene -{ - Q_OBJECT -public: - explicit CloseWindowView(QObject *parent = nullptr); - void disarm(); -Q_SIGNALS: - void requestClose(); -private Q_SLOTS: - void clicked(); - -private: - QElapsedTimer m_armTimer; -}; - -/** - * Expose-like effect which shows all windows on current desktop side-by-side, - * letting the user select active window. - */ -class PresentWindowsEffect - : public Effect -{ - Q_OBJECT - Q_PROPERTY(int layoutMode READ layoutMode) - Q_PROPERTY(bool showCaptions READ isShowCaptions) - Q_PROPERTY(bool showIcons READ isShowIcons) - Q_PROPERTY(bool doNotCloseWindows READ isDoNotCloseWindows) - Q_PROPERTY(bool ignoreMinimized READ isIgnoreMinimized) - Q_PROPERTY(int accuracy READ accuracy) - Q_PROPERTY(bool fillGaps READ isFillGaps) - Q_PROPERTY(int fadeDuration READ fadeDuration) - Q_PROPERTY(bool showPanel READ isShowPanel) - Q_PROPERTY(int leftButtonWindow READ leftButtonWindow) - Q_PROPERTY(int rightButtonWindow READ rightButtonWindow) - Q_PROPERTY(int middleButtonWindow READ middleButtonWindow) - Q_PROPERTY(int leftButtonDesktop READ leftButtonDesktop) - Q_PROPERTY(int middleButtonDesktop READ middleButtonDesktop) - Q_PROPERTY(int rightButtonDesktop READ rightButtonDesktop) - // TODO: electric borders -private: - // Structures - struct WindowData - { - EffectWindowDeletedRef deletedRef; - EffectWindowVisibleRef visibleRef; - std::chrono::milliseconds lastPresentTime = std::chrono::milliseconds::zero(); - bool visible; - bool deleted; - double opacity; - double highlight; - EffectFrame *textFrame; - EffectFrame *iconFrame; - }; - typedef QHash DataHash; - struct GridSize - { - int columns; - int rows; - }; - -public: - PresentWindowsEffect(); - ~PresentWindowsEffect() override; - - void reconfigure(ReconfigureFlags) override; - void *proxy() override; - - // Screen painting - void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override; - void paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) override; - void postPaintScreen() override; - - // Window painting - void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override; - void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override; - - // User interaction - void windowInputMouseEvent(QEvent *e) override; - void grabbedKeyboardEvent(QKeyEvent *e) override; - bool isActive() const override; - - bool touchDown(qint32 id, const QPointF &pos, quint32 time) override; - bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override; - bool touchUp(qint32 id, quint32 time) override; - - int requestedEffectChainPosition() const override - { - return 70; - } - - enum { - LayoutNatural, - LayoutRegularGrid, - LayoutFlexibleGrid, - }; // Layout modes - enum PresentWindowsMode { - ModeAllDesktops, // Shows windows of all desktops - ModeCurrentDesktop, // Shows windows on current desktop - ModeSelectedDesktop, // Shows windows of selected desktop via property (m_desktop) - ModeWindowGroup, // Shows windows selected via property - ModeWindowClass // Shows all windows of same class as selected class - }; - enum WindowMouseAction { - WindowNoAction = 0, // Nothing - WindowActivateAction = 1, // Activates the window and deactivates the effect - WindowExitAction = 2, // Deactivates the effect without activating new window - WindowToCurrentDesktopAction = 3, // Brings window to current desktop - WindowToAllDesktopsAction = 4, // Brings window to all desktops - WindowMinimizeAction = 5, // Minimizes the window - WindowCloseAction = 6 // Closes the window - }; - enum DesktopMouseAction { - DesktopNoAction = 0, // nothing - DesktopActivateAction = 1, // Activates the window and deactivates the effect - DesktopExitAction = 2, // Deactivates the effect without activating new window - DesktopShowDesktopAction = 3 // Minimizes all windows - }; - - // for properties - int layoutMode() const - { - return m_layoutMode; - } - bool isShowCaptions() const - { - return m_showCaptions; - } - bool isShowIcons() const - { - return m_showIcons; - } - bool isDoNotCloseWindows() const - { - return m_doNotCloseWindows; - } - bool isIgnoreMinimized() const - { - return m_ignoreMinimized; - } - int accuracy() const - { - return m_accuracy; - } - bool isFillGaps() const - { - return m_fillGaps; - } - int fadeDuration() const - { - return m_fadeDuration; - } - bool isShowPanel() const - { - return m_showPanel; - } - int leftButtonWindow() const - { - return m_leftButtonWindow; - } - int rightButtonWindow() const - { - return m_rightButtonWindow; - } - int middleButtonWindow() const - { - return m_middleButtonWindow; - } - int leftButtonDesktop() const - { - return m_leftButtonDesktop; - } - int middleButtonDesktop() const - { - return m_middleButtonDesktop; - } - int rightButtonDesktop() const - { - return m_rightButtonDesktop; - } -public Q_SLOTS: - Q_SCRIPTABLE void presentWindows(const QStringList &windows); - void setActive(bool active); - void toggleActive() - { - m_mode = ModeCurrentDesktop; - setActive(!m_activated); - } - void toggleActiveAllDesktops() - { - m_mode = ModeAllDesktops; - setActive(!m_activated); - } - void toggleActiveClass(); - - // EffectsHandler - void slotWindowAdded(KWin::EffectWindow *w); - void slotWindowClosed(KWin::EffectWindow *w); - void slotWindowDeleted(KWin::EffectWindow *w); - void slotWindowFrameGeometryChanged(KWin::EffectWindow *w, const QRect &old); - // atoms - void slotPropertyNotify(KWin::EffectWindow *w, long atom); - -private Q_SLOTS: - void closeWindow(); - -protected: - // Window rearranging - void rearrangeWindows(); - void reCreateGrids(); - void maybeRecreateGrids(); - void calculateWindowTransformations(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager, bool external = false); - void calculateWindowTransformationsClosest(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager); - void calculateWindowTransformationsKompose(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager); - void calculateWindowTransformationsNatural(EffectWindowList windowlist, EffectScreen *screen, - WindowMotionManager &motionManager); - - // Helper functions for window rearranging - inline double aspectRatio(EffectWindow *w) - { - return w->width() / double(w->height()); - } - inline int widthForHeight(EffectWindow *w, int height) - { - return int((height / double(w->height())) * w->width()); - } - inline int heightForWidth(EffectWindow *w, int width) - { - return int((width / double(w->width())) * w->height()); - } - bool isOverlappingAny(EffectWindow *w, const QHash &targets, const QRegion &border); - - // Filter box - void updateFilterFrame(); - - // Helper functions - bool isSelectableWindow(EffectWindow *w); - bool isVisibleWindow(EffectWindow *w); - void setHighlightedWindow(EffectWindow *w); - EffectWindow *relativeWindow(EffectWindow *w, int xdiff, int ydiff, bool wrap) const; - EffectWindow *findFirstWindow() const; - void updateCloseWindow(); - - // Helper functions for mouse actions - void mouseActionWindow(WindowMouseAction &action); - void mouseActionDesktop(DesktopMouseAction &action); - void inputEventUpdate(const QPoint &pos, QEvent::Type type = QEvent::None, Qt::MouseButton button = Qt::NoButton); - -private: - PresentWindowsEffectProxy m_proxy; - friend class PresentWindowsEffectProxy; - - // User configuration settings - int m_layoutMode; - bool m_showCaptions; - bool m_showIcons; - bool m_doNotCloseWindows; - int m_accuracy; - bool m_fillGaps; - double m_fadeDuration; - bool m_showPanel; - - // Activation - bool m_activated; - bool m_ignoreMinimized; - double m_decalOpacity; - bool m_hasKeyboardGrab; - PresentWindowsMode m_mode; - int m_desktop; - EffectWindowList m_selectedWindows; - EffectWindow *m_managerWindow; - QString m_class; - bool m_needInitialSelection; - - // Window data - WindowMotionManager m_motionManager; - DataHash m_windowData; - EffectWindow *m_highlightedWindow; - - // Timing - std::chrono::milliseconds m_lastPresentTime; - - // Grid layout info - QMap m_gridSizes; - - // Filter box - EffectFrame *m_filterFrame; - QString m_windowFilter; - - // Atoms - // Present windows for all windows of given desktop - // -1 for all desktops - long m_atomDesktop; - // Present windows for group of window ids - long m_atomWindows; - - // Mouse Actions - WindowMouseAction m_leftButtonWindow; - WindowMouseAction m_middleButtonWindow; - WindowMouseAction m_rightButtonWindow; - DesktopMouseAction m_leftButtonDesktop; - DesktopMouseAction m_middleButtonDesktop; - DesktopMouseAction m_rightButtonDesktop; - - CloseWindowView *m_closeView; - Qt::Corner m_closeButtonCorner; - struct - { - qint32 id = 0; - bool active = false; - } m_touch; -}; - -} // namespace - -#endif diff --git a/src/effects/presentwindows/presentwindows.kcfg b/src/effects/presentwindows/presentwindows.kcfg deleted file mode 100644 index 7bf0dbd66d..0000000000 --- a/src/effects/presentwindows/presentwindows.kcfg +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - 0 - - - true - - - true - - - true - - - false - - - true - - - 1 - - - true - - - 1 - - - 0 - - - 2 - - - 2 - - - 0 - - - 0 - - - diff --git a/src/effects/presentwindows/presentwindows_config.cpp b/src/effects/presentwindows/presentwindows_config.cpp deleted file mode 100644 index 5d15d2e6a8..0000000000 --- a/src/effects/presentwindows/presentwindows_config.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2007 Rivo Laks - SPDX-FileCopyrightText: 2008 Lucas Murray - - SPDX-License-Identifier: GPL-2.0-or-later -*/ -#include "presentwindows_config.h" - -#include - -// KConfigSkeleton -#include "presentwindowsconfig.h" -#include -#include - -#include -#include -#include -#include -#include - -#include - -K_PLUGIN_CLASS(KWin::PresentWindowsEffectConfig) - -namespace KWin -{ - -PresentWindowsEffectConfigForm::PresentWindowsEffectConfigForm(QWidget *parent) - : QWidget(parent) -{ - setupUi(this); -} - -PresentWindowsEffectConfig::PresentWindowsEffectConfig(QWidget *parent, const QVariantList &args) - : KCModule(parent, args) -{ - m_ui = new PresentWindowsEffectConfigForm(this); - - QVBoxLayout *layout = new QVBoxLayout(this); - - layout->addWidget(m_ui); - - // Shortcut config. The shortcut belongs to the component "kwin"! - m_actionCollection = new KActionCollection(this, QStringLiteral("kwin")); - - m_actionCollection->setComponentDisplayName(i18n("KWin")); - m_actionCollection->setConfigGroup(QStringLiteral("PresentWindows")); - m_actionCollection->setConfigGlobal(true); - - QAction *a = m_actionCollection->addAction(QStringLiteral("ExposeAll")); - a->setText(i18n("Toggle Present Windows (All desktops)")); - a->setProperty("isConfigurationAction", true); - KGlobalAccel::self()->setDefaultShortcut(a, QList() << (Qt::CTRL | Qt::Key_F10) << Qt::Key_LaunchC); - KGlobalAccel::self()->setShortcut(a, QList() << (Qt::CTRL | Qt::Key_F10) << Qt::Key_LaunchC); - - QAction *b = m_actionCollection->addAction(QStringLiteral("Expose")); - b->setText(i18n("Toggle Present Windows (Current desktop)")); - b->setProperty("isConfigurationAction", true); - KGlobalAccel::self()->setDefaultShortcut(b, QList() << (Qt::CTRL | Qt::Key_F9)); - KGlobalAccel::self()->setShortcut(b, QList() << (Qt::CTRL | Qt::Key_F9)); - - QAction *c = m_actionCollection->addAction(QStringLiteral("ExposeClass")); - c->setText(i18n("Toggle Present Windows (Window class)")); - c->setProperty("isConfigurationAction", true); - KGlobalAccel::self()->setDefaultShortcut(c, QList() << (Qt::CTRL | Qt::Key_F7)); - KGlobalAccel::self()->setShortcut(c, QList() << (Qt::CTRL | Qt::Key_F7)); - - m_ui->shortcutEditor->addCollection(m_actionCollection); - - connect(m_ui->shortcutEditor, &KShortcutsEditor::keyChange, this, &PresentWindowsEffectConfig::markAsChanged); - - PresentWindowsConfig::instance(KWIN_CONFIG); - addConfig(PresentWindowsConfig::self(), m_ui); -} - -PresentWindowsEffectConfig::~PresentWindowsEffectConfig() -{ - // If save() is called undo() has no effect - m_ui->shortcutEditor->undo(); -} - -void PresentWindowsEffectConfig::save() -{ - KCModule::save(); - m_ui->shortcutEditor->save(); - OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), - QStringLiteral("/Effects"), - QDBusConnection::sessionBus()); - interface.reconfigureEffect(QStringLiteral("presentwindows")); -} - -void PresentWindowsEffectConfig::defaults() -{ - m_ui->shortcutEditor->allDefault(); - KCModule::defaults(); -} - -} // namespace - -#include "presentwindows_config.moc" diff --git a/src/effects/presentwindows/presentwindows_config.h b/src/effects/presentwindows/presentwindows_config.h deleted file mode 100644 index 4f4902f06b..0000000000 --- a/src/effects/presentwindows/presentwindows_config.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2007 Rivo Laks - SPDX-FileCopyrightText: 2008 Lucas Murray - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#ifndef KWIN_PRESENTWINDOWS_CONFIG_H -#define KWIN_PRESENTWINDOWS_CONFIG_H - -#include - -#include "ui_presentwindows_config.h" - -namespace KWin -{ - -class PresentWindowsEffectConfigForm : public QWidget, public Ui::PresentWindowsEffectConfigForm -{ - Q_OBJECT -public: - explicit PresentWindowsEffectConfigForm(QWidget *parent); -}; - -class PresentWindowsEffectConfig : public KCModule -{ - Q_OBJECT -public: - explicit PresentWindowsEffectConfig(QWidget *parent = nullptr, const QVariantList &args = QVariantList()); - ~PresentWindowsEffectConfig() override; - -public Q_SLOTS: - void save() override; - void defaults() override; - -private: - PresentWindowsEffectConfigForm *m_ui; - KActionCollection *m_actionCollection; -}; - -} // namespace - -#endif diff --git a/src/effects/presentwindows/presentwindows_config.ui b/src/effects/presentwindows/presentwindows_config.ui deleted file mode 100644 index ceb4f9928c..0000000000 --- a/src/effects/presentwindows/presentwindows_config.ui +++ /dev/null @@ -1,487 +0,0 @@ - - - KWin::PresentWindowsEffectConfigForm - - - - 0 - 0 - 595 - 441 - - - - - - - Activation - - - - - - - 0 - 0 - - - - KShortcutsEditor::GlobalAction - - - - - - - - - - Natural Layout Settings - - - - - - Fill &gaps - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Faster - - - - - - - - 130 - 0 - - - - 1 - - - 8 - - - 1 - - - 1 - - - 1 - - - true - - - Qt::Horizontal - - - true - - - false - - - QSlider::TicksBelow - - - - - - - Nicer - - - - - - - - - - Windows - - - - - - Left button: - - - kcfg_LeftButtonWindow - - - - - - - - No action - - - - - Activate window - - - - - End effect - - - - - Bring window to current desktop - - - - - Send window to all desktops - - - - - (Un-)Minimize window - - - - - - - - Middle button: - - - kcfg_MiddleButtonWindow - - - - - - - - No action - - - - - Activate window - - - - - End effect - - - - - Bring window to current desktop - - - - - Send window to all desktops - - - - - (Un-)Minimize window - - - - - Close window - - - - - - - - Right button: - - - kcfg_RightButtonWindow - - - - - - - - No action - - - - - Activate window - - - - - End effect - - - - - Bring window to current desktop - - - - - Send window to all desktops - - - - - (Un-)Minimize window - - - - - Close window - - - - - - - - - - - Desktop - - - - QFormLayout::ExpandingFieldsGrow - - - - - Left button: - - - kcfg_LeftButtonDesktop - - - - - - - - No action - - - - - Activate window - - - - - End effect - - - - - Show desktop - - - - - - - - Middle button: - - - kcfg_MiddleButtonDesktop - - - - - - - - No action - - - - - Activate window - - - - - End effect - - - - - Show desktop - - - - - - - - Right button: - - - kcfg_RightButtonDesktop - - - - - - - - No action - - - - - Activate window - - - - - End effect - - - - - Show desktop - - - - - - - - - - - Appearance - - - - - - Layout mode: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - kcfg_LayoutMode - - - - - - - Display window &titles - - - - - - - Display window &icons - - - - - - - Ignore &minimized windows - - - - - - - Show &panels - - - - - - - - 0 - 0 - - - - - Natural - - - - - Regular Grid - - - - - Flexible Grid - - - - - - - - Provide buttons to close the windows - - - - - - - - - - - KShortcutsEditor - QWidget -
KShortcutsEditor
- 1 -
-
- - kcfg_LayoutMode - kcfg_DrawWindowCaptions - kcfg_DrawWindowIcons - kcfg_AllowClosingWindows - kcfg_IgnoreMinimized - kcfg_Accuracy - kcfg_FillGaps - - - -
diff --git a/src/effects/presentwindows/presentwindows_proxy.cpp b/src/effects/presentwindows/presentwindows_proxy.cpp deleted file mode 100644 index 969ef33015..0000000000 --- a/src/effects/presentwindows/presentwindows_proxy.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2009 Lucas Murray - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#include "presentwindows_proxy.h" -#include "presentwindows.h" - -namespace KWin -{ - -PresentWindowsEffectProxy::PresentWindowsEffectProxy(PresentWindowsEffect *effect) - : m_effect(effect) -{ -} - -PresentWindowsEffectProxy::~PresentWindowsEffectProxy() -{ -} - -void PresentWindowsEffectProxy::calculateWindowTransformations(EffectWindowList windows, EffectScreen *screen, - WindowMotionManager &manager) -{ - return m_effect->calculateWindowTransformations(windows, screen, manager, true); -} - -void PresentWindowsEffectProxy::reCreateGrids() -{ - m_effect->reCreateGrids(); -} - -} // namespace diff --git a/src/effects/presentwindows/presentwindows_proxy.h b/src/effects/presentwindows/presentwindows_proxy.h deleted file mode 100644 index bbd222f6ef..0000000000 --- a/src/effects/presentwindows/presentwindows_proxy.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - KWin - the KDE window manager - This file is part of the KDE project. - - SPDX-FileCopyrightText: 2009 Lucas Murray - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#ifndef KWIN_PRESENTWINDOWS_PROXY_H -#define KWIN_PRESENTWINDOWS_PROXY_H -#include - -namespace KWin -{ - -class PresentWindowsEffect; - -class PresentWindowsEffectProxy -{ -public: - explicit PresentWindowsEffectProxy(PresentWindowsEffect *effect); - ~PresentWindowsEffectProxy(); - - void calculateWindowTransformations(EffectWindowList windows, EffectScreen *screen, WindowMotionManager &manager); - - void reCreateGrids(); - -private: - PresentWindowsEffect *m_effect; -}; - -} // namespace - -#endif diff --git a/src/effects/presentwindows/presentwindowsconfig.kcfgc b/src/effects/presentwindows/presentwindowsconfig.kcfgc deleted file mode 100644 index 3e92ddf686..0000000000 --- a/src/effects/presentwindows/presentwindowsconfig.kcfgc +++ /dev/null @@ -1,6 +0,0 @@ -File=presentwindows.kcfg -ClassName=PresentWindowsConfig -NameSpace=KWin -Singleton=true -Mutators=true -IncludeFiles=kwinglobals.h