diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -152,12 +152,17 @@ include_directories(${KWIN_SOURCE_DIR}) set( testScriptedEffectLoader_SRCS test_scripted_effectloader.cpp + mock_abstract_client.cpp mock_effectshandler.cpp + mock_screens.cpp + mock_workspace.cpp ../effectloader.cpp ../scripting/scriptedeffect.cpp ../scripting/scriptingutils.cpp ../scripting/scripting_logging.cpp + ../screens.cpp ) +kconfig_add_kcfg_files(testScriptedEffectLoader_SRCS ../settings.kcfgc) add_executable( testScriptedEffectLoader ${testScriptedEffectLoader_SRCS}) target_link_libraries(testScriptedEffectLoader diff --git a/autotests/test_scripted_effectloader.cpp b/autotests/test_scripted_effectloader.cpp --- a/autotests/test_scripted_effectloader.cpp +++ b/autotests/test_scripted_effectloader.cpp @@ -21,6 +21,7 @@ #include "mock_effectshandler.h" #include "../scripting/scriptedeffect.h" // for mocking +#include "../cursor.h" #include "../input.h" #include "../screenedge.h" // KDE @@ -63,6 +64,13 @@ } } +static QPoint s_cursorPos = QPoint(); +QPoint Cursor::pos() +{ + return s_cursorPos; +} + + } class TestScriptedEffectLoader : public QObject diff --git a/effects.cpp b/effects.cpp --- a/effects.cpp +++ b/effects.cpp @@ -961,12 +961,12 @@ int EffectsHandlerImpl::workspaceWidth() const { - return desktopGridWidth() * displayWidth(); + return desktopGridWidth() * screens()->size().width(); } int EffectsHandlerImpl::workspaceHeight() const { - return desktopGridHeight() * displayHeight(); + return desktopGridHeight() * screens()->size().height(); } int EffectsHandlerImpl::desktopAtCoords(QPoint coords) const @@ -987,7 +987,8 @@ QPoint coords = VirtualDesktopManager::self()->grid().gridCoords(id); if (coords.x() == -1) return QPoint(-1, -1); - return QPoint(coords.x() * displayWidth(), coords.y() * displayHeight()); + const QSize displaySize = screens()->size(); + return QPoint(coords.x() * displaySize.width(), coords.y() * displaySize.height()); } int EffectsHandlerImpl::desktopAbove(int desktop, bool wrap) const diff --git a/geometry.cpp b/geometry.cpp --- a/geometry.cpp +++ b/geometry.cpp @@ -90,7 +90,7 @@ void Workspace::saveOldScreenSizes() { - olddisplaysize = QSize( displayWidth(), displayHeight()); + olddisplaysize = screens()->displaySize(); oldscreensizes.clear(); for( int i = 0; i < screens()->count(); @@ -355,6 +355,7 @@ desktop = VirtualDesktopManager::self()->current(); if (screen == -1) screen = screens()->current(); + const QSize displaySize = screens()->displaySize(); QRect sarea, warea; @@ -372,7 +373,7 @@ ? screenarea[ desktop ][ screen ] : screens()->geometry(screen); warea = workarea[ desktop ].isNull() - ? QRect(0, 0, displayWidth(), displayHeight()) + ? QRect(0, 0, displaySize.width(), displaySize.height()) : workarea[ desktop ]; } @@ -394,7 +395,7 @@ else return warea; case FullArea: - return QRect(0, 0, displayWidth(), displayHeight()); + return QRect(0, 0, displaySize.width(), displaySize.height()); } abort(); } @@ -955,7 +956,7 @@ // HACK: workarea handling is not xinerama aware, so if this strut // reserves place at a xinerama edge that's inside the virtual screen, // ignore the strut for workspace setting. - if (area == QRect(0, 0, displayWidth(), displayHeight())) { + if (area == QRect(QPoint(0, 0), screens()->displaySize())) { if (stareaL.left() < screenarea.left()) stareaL = QRect(); if (stareaR.right() > screenarea.right()) @@ -997,36 +998,38 @@ { NETExtendedStrut ext = info->extendedStrut(); NETStrut str = info->strut(); + const QSize displaySize = screens()->displaySize(); if (ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0 && (str.left != 0 || str.right != 0 || str.top != 0 || str.bottom != 0)) { // build extended from simple if (str.left != 0) { ext.left_width = str.left; ext.left_start = 0; - ext.left_end = displayHeight(); + ext.left_end = displaySize.height(); } if (str.right != 0) { ext.right_width = str.right; ext.right_start = 0; - ext.right_end = displayHeight(); + ext.right_end = displaySize.height(); } if (str.top != 0) { ext.top_width = str.top; ext.top_start = 0; - ext.top_end = displayWidth(); + ext.top_end = displaySize.width(); } if (str.bottom != 0) { ext.bottom_width = str.bottom; ext.bottom_start = 0; - ext.bottom_end = displayWidth(); + ext.bottom_end = displaySize.width(); } } return ext; } StrutRect Client::strutRect(StrutArea area) const { assert(area != StrutAreaAll); // Not valid + const QSize displaySize = screens()->displaySize(); NETExtendedStrut strutArea = strut(); switch(area) { case StrutAreaTop: @@ -1039,14 +1042,14 @@ case StrutAreaRight: if (strutArea.right_width != 0) return StrutRect(QRect( - displayWidth() - strutArea.right_width, strutArea.right_start, + displaySize.width() - strutArea.right_width, strutArea.right_start, strutArea.right_width, strutArea.right_end - strutArea.right_start ), StrutAreaRight); break; case StrutAreaBottom: if (strutArea.bottom_width != 0) return StrutRect(QRect( - strutArea.bottom_start, displayHeight() - strutArea.bottom_width, + strutArea.bottom_start, displaySize.height() - strutArea.bottom_width, strutArea.bottom_end - strutArea.bottom_start, strutArea.bottom_width ), StrutAreaBottom); break; @@ -1148,6 +1151,7 @@ QRect oldScreenArea; QRect oldGeomTall; QRect oldGeomWide; + const auto displaySize = screens()->displaySize(); if( workspace()->inUpdateClientArea()) { // we need to find the screen area as it was before the change oldScreenArea = QRect( 0, 0, workspace()->oldDisplayWidth(), workspace()->oldDisplayHeight()); @@ -1163,8 +1167,8 @@ } } else { oldScreenArea = workspace()->clientArea(ScreenArea, oldGeometry.center(), oldDesktop); - oldGeomTall = QRect(oldGeometry.x(), 0, oldGeometry.width(), displayHeight()); // Full screen height - oldGeomWide = QRect(0, oldGeometry.y(), displayWidth(), oldGeometry.height()); // Full screen width + oldGeomTall = QRect(oldGeometry.x(), 0, oldGeometry.width(), displaySize.height()); // Full screen height + oldGeomWide = QRect(0, oldGeometry.y(), displaySize.width(), oldGeometry.height()); // Full screen width } int oldTopMax = oldScreenArea.y(); int oldRightMax = oldScreenArea.x() + oldScreenArea.width(); @@ -1177,8 +1181,8 @@ int leftMax = screenArea.x(); QRect newGeom = geometryRestore(); // geometry(); QRect newClientGeom = newGeom.adjusted(border[Left], border[Top], -border[Right], -border[Bottom]); - const QRect newGeomTall = QRect(newGeom.x(), 0, newGeom.width(), displayHeight()); // Full screen height - const QRect newGeomWide = QRect(0, newGeom.y(), displayWidth(), newGeom.height()); // Full screen width + const QRect newGeomTall = QRect(newGeom.x(), 0, newGeom.width(), displaySize.height()); // Full screen height + const QRect newGeomWide = QRect(0, newGeom.y(), displaySize.width(), newGeom.height()); // Full screen width // Get the max strut point for each side where the window is (E.g. Highest point for // the bottom struts bounded by the window's left and right sides). diff --git a/plugins/platforms/x11/standalone/screens_xrandr.h b/plugins/platforms/x11/standalone/screens_xrandr.h --- a/plugins/platforms/x11/standalone/screens_xrandr.h +++ b/plugins/platforms/x11/standalone/screens_xrandr.h @@ -40,6 +40,7 @@ int number(const QPoint& pos) const override; float refreshRate(int screen) const override; QSize size(int screen) const override; + QSize displaySize() const override; using QObject::event; bool event(xcb_generic_event_t *event) override; diff --git a/plugins/platforms/x11/standalone/screens_xrandr.cpp b/plugins/platforms/x11/standalone/screens_xrandr.cpp --- a/plugins/platforms/x11/standalone/screens_xrandr.cpp +++ b/plugins/platforms/x11/standalone/screens_xrandr.cpp @@ -126,7 +126,7 @@ return QRect(); } return m_geometries.at(screen).isValid() ? m_geometries.at(screen) : - QRect(0, 0, displayWidth(), displayHeight()); // xinerama, lacks RandR + QRect(QPoint(0, 0), displaySize()); // xinerama, lacks RandR } QString XRandRScreens::name(int screen) const @@ -188,4 +188,13 @@ return false; } +QSize XRandRScreens::displaySize() const +{ + xcb_screen_t *screen = defaultScreen(); + if (!screen) { + return Screens::size(); + } + return QSize(screen->width_in_pixels, screen->height_in_pixels); +} + } // namespace diff --git a/scene_xrender.cpp b/scene_xrender.cpp --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -33,6 +33,7 @@ #include "main.h" #include "overlaywindow.h" #include "platform.h" +#include "screens.h" #include "xcbutils.h" #include "kwinxrenderutils.h" #include "decorations/decoratedclient.h" @@ -173,29 +174,31 @@ void X11XRenderBackend::createBuffer() { xcb_pixmap_t pixmap = xcb_generate_id(connection()); - xcb_create_pixmap(connection(), Xcb::defaultDepth(), pixmap, rootWindow(), displayWidth(), displayHeight()); + const auto displaySize = screens()->displaySize(); + xcb_create_pixmap(connection(), Xcb::defaultDepth(), pixmap, rootWindow(), displaySize.width(), displaySize.height()); xcb_render_picture_t b = xcb_generate_id(connection()); xcb_render_create_picture(connection(), b, pixmap, m_format, 0, NULL); xcb_free_pixmap(connection(), pixmap); // The picture owns the pixmap now setBuffer(b); } void X11XRenderBackend::present(int mask, const QRegion &damage) { + const auto displaySize = screens()->displaySize(); if (mask & Scene::PAINT_SCREEN_REGION) { // Use the damage region as the clip region for the root window XFixesRegion frontRegion(damage); xcb_xfixes_set_picture_clip_region(connection(), m_front, frontRegion, 0, 0); // copy composed buffer to the root window xcb_xfixes_set_picture_clip_region(connection(), buffer(), XCB_XFIXES_REGION_NONE, 0, 0); xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer(), XCB_RENDER_PICTURE_NONE, - m_front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight()); + m_front, 0, 0, 0, 0, 0, 0, displaySize.width(), displaySize.height()); xcb_xfixes_set_picture_clip_region(connection(), m_front, XCB_XFIXES_REGION_NONE, 0, 0); xcb_flush(connection()); } else { // copy composed buffer to the root window xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, buffer(), XCB_RENDER_PICTURE_NONE, - m_front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight()); + m_front, 0, 0, 0, 0, 0, 0, displaySize.width(), displaySize.height()); xcb_flush(connection()); } } diff --git a/screenedge.cpp b/screenedge.cpp --- a/screenedge.cpp +++ b/screenedge.cpp @@ -417,7 +417,7 @@ const uint interimDesktop = desktop; desktop = vds->toLeft(desktop, vds->isNavigationWrappingAround()); if (desktop != interimDesktop) - pos.setX(displayWidth() - 1 - OFFSET); + pos.setX(screens()->size().width() - 1 - OFFSET); } else if (isRight()) { const uint interimDesktop = desktop; desktop = vds->toRight(desktop, vds->isNavigationWrappingAround()); @@ -428,7 +428,7 @@ const uint interimDesktop = desktop; desktop = vds->above(desktop, vds->isNavigationWrappingAround()); if (desktop != interimDesktop) - pos.setY(displayHeight() - 1 - OFFSET); + pos.setY(screens()->size().height() - 1 - OFFSET); } else if (isBottom()) { const uint interimDesktop = desktop; desktop = vds->below(desktop, vds->isNavigationWrappingAround()); diff --git a/screens.h b/screens.h --- a/screens.h +++ b/screens.h @@ -105,6 +105,18 @@ int intersecting(const QRect &r) const; + /** + * The virtual bounding size of all screens combined. + * The default implementation returns the same as @link{size} and that is the + * method which should be preferred. + * + * This method is only for cases where the platform specific implementation needs + * to support different virtual sizes like on X11 with XRandR panning. + * + * @see size + **/ + virtual QSize displaySize() const; + public Q_SLOTS: void reconfigure(); diff --git a/screens.cpp b/screens.cpp --- a/screens.cpp +++ b/screens.cpp @@ -185,6 +185,11 @@ return cnt; } +QSize Screens::displaySize() const +{ + return size(); +} + BasicScreens::BasicScreens(Platform *backend, QObject *parent) : Screens(parent) , m_backend(backend) diff --git a/scripting/scriptedeffect.cpp b/scripting/scriptedeffect.cpp --- a/scripting/scriptedeffect.cpp +++ b/scripting/scriptedeffect.cpp @@ -22,6 +22,7 @@ #include "meta.h" #include "scriptingutils.h" #include "workspace_wrapper.h" +#include "../screens.h" #include "../screenedge.h" #include "scripting_logging.h" // KDE @@ -71,14 +72,14 @@ { Q_UNUSED(context) Q_UNUSED(engine) - return displayWidth(); + return screens()->displaySize().width(); } QScriptValue kwinEffectDisplayHeight(QScriptContext *context, QScriptEngine *engine) { Q_UNUSED(context) Q_UNUSED(engine) - return displayHeight(); + return screens()->displaySize().height(); } QScriptValue kwinScriptGlobalShortcut(QScriptContext *context, QScriptEngine *engine) diff --git a/scripting/workspace_wrapper.cpp b/scripting/workspace_wrapper.cpp --- a/scripting/workspace_wrapper.cpp +++ b/scripting/workspace_wrapper.cpp @@ -226,17 +226,17 @@ QSize WorkspaceWrapper::displaySize() const { - return QSize(KWin::displayWidth(), KWin::displayHeight()); + return screens()->displaySize(); } int WorkspaceWrapper::displayWidth() const { - return KWin::displayWidth(); + return displaySize().width(); } int WorkspaceWrapper::displayHeight() const { - return KWin::displayHeight(); + return displaySize().height(); } QRect WorkspaceWrapper::clientArea(ClientAreaOption option, const QPoint &p, int desktop) const