File indexing completed on 2024-05-19 05:32:25

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2010 Rohan Prabhu <rohan@rohanprabhu.com>
0006     SPDX-FileCopyrightText: 2011, 2012 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "workspace_wrapper.h"
0012 #include "core/output.h"
0013 #include "core/outputbackend.h"
0014 #include "cursor.h"
0015 #include "effect/effecthandler.h"
0016 #include "outline.h"
0017 #include "tiles/tilemanager.h"
0018 #include "virtualdesktops.h"
0019 #include "workspace.h"
0020 #include "x11window.h"
0021 #if KWIN_BUILD_ACTIVITIES
0022 #include "activities.h"
0023 #endif
0024 
0025 #include <QQmlEngine>
0026 
0027 namespace KWin
0028 {
0029 
0030 WorkspaceWrapper::WorkspaceWrapper(QObject *parent)
0031     : QObject(parent)
0032 {
0033     KWin::Workspace *ws = KWin::Workspace::self();
0034     KWin::VirtualDesktopManager *vds = KWin::VirtualDesktopManager::self();
0035     connect(ws, &Workspace::windowAdded, this, &WorkspaceWrapper::windowAdded);
0036     connect(ws, &Workspace::windowRemoved, this, &WorkspaceWrapper::windowRemoved);
0037     connect(ws, &Workspace::windowActivated, this, &WorkspaceWrapper::windowActivated);
0038     connect(vds, &VirtualDesktopManager::desktopAdded, this, &WorkspaceWrapper::desktopsChanged);
0039     connect(vds, &VirtualDesktopManager::desktopRemoved, this, &WorkspaceWrapper::desktopsChanged);
0040     connect(vds, &VirtualDesktopManager::layoutChanged, this, &WorkspaceWrapper::desktopLayoutChanged);
0041     connect(vds, &VirtualDesktopManager::currentChanged, this, &WorkspaceWrapper::currentDesktopChanged);
0042 #if KWIN_BUILD_ACTIVITIES
0043     if (KWin::Activities *activities = ws->activities()) {
0044         connect(activities, &Activities::currentChanged, this, &WorkspaceWrapper::currentActivityChanged);
0045         connect(activities, &Activities::added, this, &WorkspaceWrapper::activitiesChanged);
0046         connect(activities, &Activities::added, this, &WorkspaceWrapper::activityAdded);
0047         connect(activities, &Activities::removed, this, &WorkspaceWrapper::activitiesChanged);
0048         connect(activities, &Activities::removed, this, &WorkspaceWrapper::activityRemoved);
0049     }
0050 #endif
0051     connect(ws, &Workspace::geometryChanged, this, &WorkspaceWrapper::virtualScreenSizeChanged);
0052     connect(ws, &Workspace::geometryChanged, this, &WorkspaceWrapper::virtualScreenGeometryChanged);
0053     connect(ws, &Workspace::outputsChanged, this, &WorkspaceWrapper::screensChanged);
0054     connect(Cursors::self()->mouse(), &Cursor::posChanged, this, &WorkspaceWrapper::cursorPosChanged);
0055 }
0056 
0057 VirtualDesktop *WorkspaceWrapper::currentDesktop() const
0058 {
0059     return VirtualDesktopManager::self()->currentDesktop();
0060 }
0061 
0062 QList<VirtualDesktop *> WorkspaceWrapper::desktops() const
0063 {
0064     return VirtualDesktopManager::self()->desktops();
0065 }
0066 
0067 void WorkspaceWrapper::setCurrentDesktop(VirtualDesktop *desktop)
0068 {
0069     VirtualDesktopManager::self()->setCurrent(desktop);
0070 }
0071 
0072 Window *WorkspaceWrapper::activeWindow() const
0073 {
0074     return workspace()->activeWindow();
0075 }
0076 
0077 QString WorkspaceWrapper::currentActivity() const
0078 {
0079 #if KWIN_BUILD_ACTIVITIES
0080     if (!Workspace::self()->activities()) {
0081         return QString();
0082     }
0083     return Workspace::self()->activities()->current();
0084 #else
0085     return QString();
0086 #endif
0087 }
0088 
0089 void WorkspaceWrapper::setCurrentActivity(const QString &activity)
0090 {
0091 #if KWIN_BUILD_ACTIVITIES
0092     if (Workspace::self()->activities()) {
0093         Workspace::self()->activities()->setCurrent(activity);
0094     }
0095 #endif
0096 }
0097 
0098 QStringList WorkspaceWrapper::activityList() const
0099 {
0100 #if KWIN_BUILD_ACTIVITIES
0101     if (!Workspace::self()->activities()) {
0102         return QStringList();
0103     }
0104     return Workspace::self()->activities()->all();
0105 #else
0106     return QStringList();
0107 #endif
0108 }
0109 
0110 QPoint WorkspaceWrapper::cursorPos() const
0111 {
0112     return Cursors::self()->mouse()->pos().toPoint();
0113 }
0114 
0115 #define SLOTWRAPPER(name)          \
0116     void WorkspaceWrapper::name()  \
0117     {                              \
0118         Workspace::self()->name(); \
0119     }
0120 
0121 SLOTWRAPPER(slotToggleShowDesktop)
0122 
0123 SLOTWRAPPER(slotWindowMaximize)
0124 SLOTWRAPPER(slotWindowMaximizeVertical)
0125 SLOTWRAPPER(slotWindowMaximizeHorizontal)
0126 SLOTWRAPPER(slotWindowMinimize)
0127 SLOTWRAPPER(slotWindowShade)
0128 SLOTWRAPPER(slotWindowRaise)
0129 SLOTWRAPPER(slotWindowLower)
0130 SLOTWRAPPER(slotWindowRaiseOrLower)
0131 SLOTWRAPPER(slotActivateAttentionWindow)
0132 SLOTWRAPPER(slotWindowMoveLeft)
0133 SLOTWRAPPER(slotWindowMoveRight)
0134 SLOTWRAPPER(slotWindowMoveUp)
0135 SLOTWRAPPER(slotWindowMoveDown)
0136 SLOTWRAPPER(slotWindowExpandHorizontal)
0137 SLOTWRAPPER(slotWindowExpandVertical)
0138 SLOTWRAPPER(slotWindowShrinkHorizontal)
0139 SLOTWRAPPER(slotWindowShrinkVertical)
0140 
0141 SLOTWRAPPER(slotIncreaseWindowOpacity)
0142 SLOTWRAPPER(slotLowerWindowOpacity)
0143 
0144 SLOTWRAPPER(slotWindowOperations)
0145 SLOTWRAPPER(slotWindowClose)
0146 SLOTWRAPPER(slotWindowMove)
0147 SLOTWRAPPER(slotWindowResize)
0148 SLOTWRAPPER(slotWindowAbove)
0149 SLOTWRAPPER(slotWindowBelow)
0150 SLOTWRAPPER(slotWindowOnAllDesktops)
0151 SLOTWRAPPER(slotWindowFullScreen)
0152 SLOTWRAPPER(slotWindowNoBorder)
0153 
0154 SLOTWRAPPER(slotWindowToNextDesktop)
0155 SLOTWRAPPER(slotWindowToPreviousDesktop)
0156 SLOTWRAPPER(slotWindowToDesktopRight)
0157 SLOTWRAPPER(slotWindowToDesktopLeft)
0158 SLOTWRAPPER(slotWindowToDesktopUp)
0159 SLOTWRAPPER(slotWindowToDesktopDown)
0160 
0161 SLOTWRAPPER(slotWindowToPrevScreen)
0162 SLOTWRAPPER(slotWindowToNextScreen)
0163 SLOTWRAPPER(slotWindowToLeftScreen)
0164 SLOTWRAPPER(slotWindowToRightScreen)
0165 SLOTWRAPPER(slotWindowToAboveScreen)
0166 SLOTWRAPPER(slotWindowToBelowScreen)
0167 
0168 SLOTWRAPPER(slotSwitchToPrevScreen)
0169 SLOTWRAPPER(slotSwitchToNextScreen)
0170 SLOTWRAPPER(slotSwitchToLeftScreen)
0171 SLOTWRAPPER(slotSwitchToRightScreen)
0172 SLOTWRAPPER(slotSwitchToAboveScreen)
0173 SLOTWRAPPER(slotSwitchToBelowScreen)
0174 
0175 #undef SLOTWRAPPER
0176 
0177 #define SLOTWRAPPER(name, modes)                   \
0178     void WorkspaceWrapper::name()                  \
0179     {                                              \
0180         Workspace::self()->quickTileWindow(modes); \
0181     }
0182 
0183 SLOTWRAPPER(slotWindowQuickTileLeft, QuickTileFlag::Left)
0184 SLOTWRAPPER(slotWindowQuickTileRight, QuickTileFlag::Right)
0185 SLOTWRAPPER(slotWindowQuickTileTop, QuickTileFlag::Top)
0186 SLOTWRAPPER(slotWindowQuickTileBottom, QuickTileFlag::Bottom)
0187 SLOTWRAPPER(slotWindowQuickTileTopLeft, QuickTileFlag::Top | QuickTileFlag::Left)
0188 SLOTWRAPPER(slotWindowQuickTileTopRight, QuickTileFlag::Top | QuickTileFlag::Right)
0189 SLOTWRAPPER(slotWindowQuickTileBottomLeft, QuickTileFlag::Bottom | QuickTileFlag::Left)
0190 SLOTWRAPPER(slotWindowQuickTileBottomRight, QuickTileFlag::Bottom | QuickTileFlag::Right)
0191 
0192 #undef SLOTWRAPPER
0193 
0194 #define SLOTWRAPPER(name, direction)                           \
0195     void WorkspaceWrapper::name()                              \
0196     {                                                          \
0197         Workspace::self()->switchWindow(Workspace::direction); \
0198     }
0199 
0200 SLOTWRAPPER(slotSwitchWindowUp, DirectionNorth)
0201 SLOTWRAPPER(slotSwitchWindowDown, DirectionSouth)
0202 SLOTWRAPPER(slotSwitchWindowRight, DirectionEast)
0203 SLOTWRAPPER(slotSwitchWindowLeft, DirectionWest)
0204 
0205 #undef SLOTWRAPPER
0206 
0207 #define SLOTWRAPPER(name, direction)                                                                                       \
0208     void WorkspaceWrapper::name()                                                                                          \
0209     {                                                                                                                      \
0210         VirtualDesktopManager::self()->moveTo(VirtualDesktopManager::Direction::direction, options->isRollOverDesktops()); \
0211     }
0212 
0213 SLOTWRAPPER(slotSwitchDesktopNext, Next)
0214 SLOTWRAPPER(slotSwitchDesktopPrevious, Previous)
0215 SLOTWRAPPER(slotSwitchDesktopRight, Right)
0216 SLOTWRAPPER(slotSwitchDesktopLeft, Left)
0217 SLOTWRAPPER(slotSwitchDesktopUp, Up)
0218 SLOTWRAPPER(slotSwitchDesktopDown, Down)
0219 
0220 #undef SLOTWRAPPER
0221 
0222 void WorkspaceWrapper::setActiveWindow(KWin::Window *window)
0223 {
0224     KWin::Workspace::self()->activateWindow(window);
0225 }
0226 
0227 QSize WorkspaceWrapper::workspaceSize() const
0228 {
0229     return QSize(workspaceWidth(), workspaceHeight());
0230 }
0231 
0232 QRectF WorkspaceWrapper::clientArea(ClientAreaOption option, const KWin::Window *c) const
0233 {
0234     if (!c) {
0235         return QRectF();
0236     }
0237     return Workspace::self()->clientArea(static_cast<clientAreaOption>(option), c);
0238 }
0239 
0240 QRectF WorkspaceWrapper::clientArea(ClientAreaOption option, KWin::Window *c) const
0241 {
0242     if (!c) {
0243         return QRectF();
0244     }
0245     return Workspace::self()->clientArea(static_cast<clientAreaOption>(option), c);
0246 }
0247 
0248 QRectF WorkspaceWrapper::clientArea(ClientAreaOption option, Output *output, VirtualDesktop *desktop) const
0249 {
0250     return workspace()->clientArea(static_cast<clientAreaOption>(option), output, desktop);
0251 }
0252 
0253 void WorkspaceWrapper::createDesktop(int position, const QString &name) const
0254 {
0255     VirtualDesktopManager::self()->createVirtualDesktop(position, name);
0256 }
0257 
0258 void WorkspaceWrapper::removeDesktop(VirtualDesktop *desktop) const
0259 {
0260     VirtualDesktopManager::self()->removeVirtualDesktop(desktop->id());
0261 }
0262 
0263 QString WorkspaceWrapper::supportInformation() const
0264 {
0265     return Workspace::self()->supportInformation();
0266 }
0267 
0268 void WorkspaceWrapper::showOutline(const QRect &geometry)
0269 {
0270     workspace()->outline()->show(geometry);
0271 }
0272 
0273 void WorkspaceWrapper::showOutline(int x, int y, int width, int height)
0274 {
0275     workspace()->outline()->show(QRect(x, y, width, height));
0276 }
0277 
0278 void WorkspaceWrapper::hideOutline()
0279 {
0280     workspace()->outline()->hide();
0281 }
0282 
0283 QList<KWin::Window *> WorkspaceWrapper::stackingOrder() const
0284 {
0285     return workspace()->stackingOrder();
0286 }
0287 
0288 void WorkspaceWrapper::raiseWindow(KWin::Window *window)
0289 {
0290     if (window) {
0291         KWin::Workspace::self()->raiseWindow(window);
0292     }
0293 }
0294 
0295 Window *WorkspaceWrapper::getClient(qulonglong windowId)
0296 {
0297     auto window = Workspace::self()->findClient(Predicate::WindowMatch, windowId);
0298     QQmlEngine::setObjectOwnership(window, QQmlEngine::CppOwnership);
0299     return window;
0300 }
0301 
0302 QList<KWin::Window *> WorkspaceWrapper::windowAt(const QPointF &pos, int count) const
0303 {
0304     QList<KWin::Window *> result;
0305     int found = 0;
0306     const QList<Window *> &stacking = workspace()->stackingOrder();
0307     if (stacking.isEmpty()) {
0308         return result;
0309     }
0310     auto it = stacking.end();
0311     do {
0312         if (found == count) {
0313             return result;
0314         }
0315         --it;
0316         Window *window = (*it);
0317         if (window->isDeleted()) {
0318             continue;
0319         }
0320         if (!window->isOnCurrentActivity() || !window->isOnCurrentDesktop() || window->isMinimized() || window->isHidden() || window->isHiddenByShowDesktop()) {
0321             continue;
0322         }
0323         if (window->hitTest(pos)) {
0324             result.append(window);
0325             found++;
0326         }
0327     } while (it != stacking.begin());
0328     return result;
0329 }
0330 
0331 bool WorkspaceWrapper::isEffectActive(const QString &pluginId) const
0332 {
0333     if (!effects) {
0334         return false;
0335     }
0336     return effects->isEffectActive(pluginId);
0337 }
0338 
0339 QSize WorkspaceWrapper::desktopGridSize() const
0340 {
0341     return VirtualDesktopManager::self()->grid().size();
0342 }
0343 
0344 int WorkspaceWrapper::desktopGridWidth() const
0345 {
0346     return desktopGridSize().width();
0347 }
0348 
0349 int WorkspaceWrapper::desktopGridHeight() const
0350 {
0351     return desktopGridSize().height();
0352 }
0353 
0354 int WorkspaceWrapper::workspaceHeight() const
0355 {
0356     return desktopGridHeight() * workspace()->geometry().height();
0357 }
0358 
0359 int WorkspaceWrapper::workspaceWidth() const
0360 {
0361     return desktopGridWidth() * workspace()->geometry().width();
0362 }
0363 
0364 Output *WorkspaceWrapper::activeScreen() const
0365 {
0366     return workspace()->activeOutput();
0367 }
0368 
0369 QList<Output *> WorkspaceWrapper::screens() const
0370 {
0371     return workspace()->outputs();
0372 }
0373 
0374 Output *WorkspaceWrapper::screenAt(const QPointF &pos) const
0375 {
0376     auto output = workspace()->outputAt(pos);
0377     QQmlEngine::setObjectOwnership(output, QQmlEngine::CppOwnership);
0378     return output;
0379 }
0380 
0381 QRect WorkspaceWrapper::virtualScreenGeometry() const
0382 {
0383     return workspace()->geometry();
0384 }
0385 
0386 QSize WorkspaceWrapper::virtualScreenSize() const
0387 {
0388     return workspace()->geometry().size();
0389 }
0390 
0391 void WorkspaceWrapper::sendClientToScreen(Window *client, Output *output)
0392 {
0393     workspace()->sendWindowToOutput(client, output);
0394 }
0395 
0396 KWin::TileManager *WorkspaceWrapper::tilingForScreen(const QString &screenName) const
0397 {
0398     Output *output = kwinApp()->outputBackend()->findOutput(screenName);
0399     if (output) {
0400         auto tileManager = workspace()->tileManager(output);
0401         QQmlEngine::setObjectOwnership(tileManager, QQmlEngine::CppOwnership);
0402         return tileManager;
0403     }
0404     return nullptr;
0405 }
0406 
0407 KWin::TileManager *WorkspaceWrapper::tilingForScreen(Output *output) const
0408 {
0409     auto tileManager = workspace()->tileManager(output);
0410     QQmlEngine::setObjectOwnership(tileManager, QQmlEngine::CppOwnership);
0411     return tileManager;
0412 }
0413 
0414 QtScriptWorkspaceWrapper::QtScriptWorkspaceWrapper(QObject *parent)
0415     : WorkspaceWrapper(parent)
0416 {
0417 }
0418 
0419 QList<KWin::Window *> QtScriptWorkspaceWrapper::windowList() const
0420 {
0421     return workspace()->windows();
0422 }
0423 
0424 QQmlListProperty<KWin::Window> DeclarativeScriptWorkspaceWrapper::windows()
0425 {
0426     return QQmlListProperty<KWin::Window>(this, nullptr, &DeclarativeScriptWorkspaceWrapper::countWindowList, &DeclarativeScriptWorkspaceWrapper::atWindowList);
0427 }
0428 
0429 qsizetype DeclarativeScriptWorkspaceWrapper::countWindowList(QQmlListProperty<KWin::Window> *windows)
0430 {
0431     return workspace()->windows().size();
0432 }
0433 
0434 KWin::Window *DeclarativeScriptWorkspaceWrapper::atWindowList(QQmlListProperty<KWin::Window> *windows, qsizetype index)
0435 {
0436     return workspace()->windows().at(index);
0437 }
0438 
0439 DeclarativeScriptWorkspaceWrapper::DeclarativeScriptWorkspaceWrapper(QObject *parent)
0440     : WorkspaceWrapper(parent)
0441 {
0442 }
0443 
0444 } // KWin
0445 
0446 #include "moc_workspace_wrapper.cpp"