diff --git a/autotests/mock_screens.cpp b/autotests/mock_screens.cpp index 84fce28335..6129492c62 100644 --- a/autotests/mock_screens.cpp +++ b/autotests/mock_screens.cpp @@ -37,6 +37,11 @@ QRect MockScreens::geometry(int screen) const return m_geometries.at(screen); } +float MockScreens::refreshRate(int screen) const +{ + return 60.0f; +} + QSize MockScreens::size(int screen) const { return geometry(screen).size(); diff --git a/autotests/mock_screens.h b/autotests/mock_screens.h index 3bc6c38283..d97fcaf3c7 100644 --- a/autotests/mock_screens.h +++ b/autotests/mock_screens.h @@ -33,6 +33,7 @@ public: virtual ~MockScreens(); QRect geometry(int screen) const override; int number(const QPoint &pos) const override; + float refreshRate(int screen) const override; QSize size(int screen) const override; void init() override; diff --git a/screens.cpp b/screens.cpp index 4f9a70146a..5f469eac62 100644 --- a/screens.cpp +++ b/screens.cpp @@ -86,6 +86,18 @@ void Screens::init() m_currentFollowsMouse = settings.activeMouseScreen(); } +QString Screens::name(int screen) const +{ + qWarning("%s::name(int screen) is a stub, please reimplement it!", metaObject()->className()); + return QLatin1String("DUMMY"); +} + +float Screens::refreshRate(int screen) const +{ + qWarning("%s::refreshRate(int screen) is a stub, please reimplement it!", metaObject()->className()); + return 60.0f; +} + void Screens::reconfigure() { if (!m_config) { diff --git a/screens.h b/screens.h index afe71560da..7828614dbe 100644 --- a/screens.h +++ b/screens.h @@ -69,6 +69,10 @@ public: * @see geometryChanged() **/ QRect geometry() const; + /** + * @returns current refreshrate of the @p screen. + **/ + virtual float refreshRate(int screen) const; /** * @returns size of the @p screen. * diff --git a/screens_xrandr.cpp b/screens_xrandr.cpp index dd8f809f17..6f63509a6d 100644 --- a/screens_xrandr.cpp +++ b/screens_xrandr.cpp @@ -20,6 +20,7 @@ along with this program. If not, see . #include "screens_xrandr.h" #include "xcbutils.h" + namespace KWin { @@ -36,6 +37,7 @@ void XRandRScreens::update() { auto fallback = [this]() { m_geometries << QRect(); + m_refreshRates << -1.0f; setCount(1); }; m_geometries.clear(); @@ -45,16 +47,35 @@ void XRandRScreens::update() return; } xcb_randr_crtc_t *crtcs = resources.crtcs(); + xcb_randr_mode_info_t *modes = resources.modes(); QVector infos(resources->num_crtcs); for (int i = 0; i < resources->num_crtcs; ++i) { infos[i] = Xcb::RandR::CrtcInfo(crtcs[i], resources->config_timestamp); } + for (int i = 0; i < resources->num_crtcs; ++i) { + float refreshRate = -1.0f; Xcb::RandR::CrtcInfo info(infos.at(i)); + for (int j = 0; j < resources->num_modes; ++j) { + if (info->mode == modes[j].id) { + if (modes[j].htotal*modes[j].vtotal) { // BUG 313996 + // refresh rate calculation - WTF was wikipedia 1998 when I needed it? + int dotclock = modes[j].dot_clock, + vtotal = modes[j].vtotal; + if (modes[j].mode_flags & XCB_RANDR_MODE_FLAG_INTERLACE) + dotclock *= 2; + if (modes[j].mode_flags & XCB_RANDR_MODE_FLAG_DOUBLE_SCAN) + vtotal *= 2; + refreshRate = dotclock/float(modes[j].htotal*vtotal); + } + break; // found mode + } + } const QRect geo = info.rect(); if (geo.isValid()) { m_geometries << geo; + m_refreshRates << refreshRate; } } if (m_geometries.isEmpty()) { @@ -103,6 +124,14 @@ int XRandRScreens::number(const QPoint &pos) const return bestScreen; } +float XRandRScreens::refreshRate(int screen) const +{ + if (screen >= m_refreshRates.size() || screen < 0) { + return -1.0f; + } + return m_refreshRates.at(screen); +} + QSize XRandRScreens::size(int screen) const { const QRect geo = geometry(screen); diff --git a/screens_xrandr.h b/screens_xrandr.h index ed96241efe..7cfba3bb32 100644 --- a/screens_xrandr.h +++ b/screens_xrandr.h @@ -37,6 +37,7 @@ public: void init() override; QRect geometry(int screen) const override; int number(const QPoint& pos) const override; + float refreshRate(int screen) const override; QSize size(int screen) const override; using QObject::event; @@ -49,6 +50,7 @@ private: template void update(); QVector m_geometries; + QVector m_refreshRates; }; } // namespace