diff --git a/CMakeLists.txt b/CMakeLists.txt index 81873d4fe1..36c69a9fea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS DBus Quick QuickWidgets + Sensors Script UiTools Widgets @@ -465,6 +466,7 @@ set(kwin_KDEINIT_SRCS moving_client_x11_filter.cpp window_property_notify_x11_filter.cpp rootinfo_filter.cpp + orientation_sensor.cpp ) if(KWIN_BUILD_TABBOX) @@ -541,6 +543,7 @@ set(kwin_QT_LIBS Qt5::Concurrent Qt5::DBus Qt5::Quick + Qt5::Sensors Qt5::Script ) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index f15229b485..bcc7d1faa0 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -161,6 +161,7 @@ set( testScriptedEffectLoader_SRCS ../scripting/scriptingutils.cpp ../scripting/scripting_logging.cpp ../screens.cpp + ../orientation_sensor.cpp ) kconfig_add_kcfg_files(testScriptedEffectLoader_SRCS ../settings.kcfgc) add_executable( testScriptedEffectLoader ${testScriptedEffectLoader_SRCS}) @@ -169,11 +170,13 @@ target_link_libraries(testScriptedEffectLoader Qt5::Concurrent Qt5::Qml Qt5::Script + Qt5::Sensors Qt5::Test Qt5::X11Extras KF5::ConfigGui KF5::GlobalAccel KF5::I18n + KF5::Notifications KF5::Package kwineffects kwin4_effect_builtins @@ -229,16 +232,20 @@ set( testScreens_SRCS mock_workspace.cpp ../screens.cpp ../x11eventfilter.cpp + ../orientation_sensor.cpp ) kconfig_add_kcfg_files(testScreens_SRCS ../settings.kcfgc) add_executable( testScreens ${testScreens_SRCS}) target_include_directories(testScreens BEFORE PRIVATE ./) target_link_libraries(testScreens + Qt5::Sensors Qt5::Test Qt5::X11Extras KF5::ConfigCore KF5::ConfigGui + KF5::I18n + KF5::Notifications KF5::WindowSystem ) @@ -258,14 +265,18 @@ set( testXRandRScreens_SRCS ../plugins/platforms/x11/standalone/screens_xrandr.cpp ../xcbutils.cpp # init of extensions ../x11eventfilter.cpp + ../orientation_sensor.cpp ) kconfig_add_kcfg_files(testXRandRScreens_SRCS ../settings.kcfgc) add_executable( testXRandRScreens ${testXRandRScreens_SRCS} ) target_link_libraries( testXRandRScreens Qt5::Test Qt5::Gui + Qt5::Sensors KF5::ConfigCore KF5::ConfigGui + KF5::I18n + KF5::Notifications KF5::WindowSystem XCB::XCB XCB::RANDR @@ -296,6 +307,7 @@ set( testScreenEdges_SRCS ../virtualdesktops.cpp ../xcbutils.cpp # init of extensions ../plugins/platforms/x11/standalone/edge.cpp + ../orientation_sensor.cpp ) kconfig_add_kcfg_files(testScreenEdges_SRCS ../settings.kcfgc) qt5_add_dbus_interface( testScreenEdges_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/../org.freedesktop.ScreenSaver.xml screenlocker_interface) @@ -305,12 +317,14 @@ set_target_properties(testScreenEdges PROPERTIES COMPILE_DEFINITIONS "NO_NONE_WI target_include_directories(testScreenEdges BEFORE PRIVATE ./) target_link_libraries(testScreenEdges Qt5::DBus + Qt5::Sensors Qt5::Test Qt5::X11Extras KF5::ConfigCore KF5::ConfigGui KF5::I18n KF5::GlobalAccel + KF5::Notifications KF5::WindowSystem XCB::XCB XCB::RANDR diff --git a/orientation_sensor.cpp b/orientation_sensor.cpp new file mode 100644 index 0000000000..7d9dcd5c85 --- /dev/null +++ b/orientation_sensor.cpp @@ -0,0 +1,126 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "orientation_sensor.h" + +#include +#include + +#include +#include + +namespace KWin +{ + +OrientationSensor::OrientationSensor(QObject *parent) + : QObject(parent) + , m_sensor(new QOrientationSensor(this)) +{ + connect(m_sensor, &QOrientationSensor::readingChanged, this, + [this] { + auto toOrientation = [] (auto reading) { + switch (reading->orientation()) { + case QOrientationReading::Undefined: + return OrientationSensor::Orientation::Undefined; + case QOrientationReading::TopUp: + return OrientationSensor::Orientation::TopUp; + case QOrientationReading::TopDown: + return OrientationSensor::Orientation::TopDown; + case QOrientationReading::LeftUp: + return OrientationSensor::Orientation::LeftUp; + case QOrientationReading::RightUp: + return OrientationSensor::Orientation::RightUp; + case QOrientationReading::FaceUp: + return OrientationSensor::Orientation::FaceUp; + case QOrientationReading::FaceDown: + return OrientationSensor::Orientation::FaceDown; + default: + Q_UNREACHABLE(); + } + }; + const auto orientation = toOrientation(m_sensor->reading()); + if (m_orientation != orientation) { + m_orientation = orientation; + emit orientationChanged(); + } + } + ); + connect(m_sensor, &QOrientationSensor::activeChanged, this, + [this] { + if (!m_sni) { + return; + } + if (m_sensor->isActive()) { + m_sni->setToolTipTitle(i18n("Automatic screen rotation is enabled")); + } else { + m_sni->setToolTipTitle(i18n("Automatic screen rotation is disabled")); + } + } + ); +} + +OrientationSensor::~OrientationSensor() = default; + +void OrientationSensor::setEnabled(bool enabled) +{ + if (m_enabled == enabled) { + return; + } + m_enabled = enabled; + if (m_enabled) { + setupStatusNotifier(); + } else { + delete m_sni; + m_sni = nullptr; + } + startStopSensor(); +} + +void OrientationSensor::setupStatusNotifier() +{ + if (m_sni) { + return; + } + m_sni = new KStatusNotifierItem(QStringLiteral("kwin-automatic-rotation"), this); + m_sni->setStandardActionsEnabled(false); + m_sni->setCategory(KStatusNotifierItem::Hardware); + m_sni->setStatus(KStatusNotifierItem::Passive); + m_sni->setTitle(i18n("Automatic Screen Rotation")); + // TODO: proper icon with state + m_sni->setIconByName(QStringLiteral("preferences-desktop-display")); + // we start disabled, it gets updated when the sensor becomes active + m_sni->setToolTipTitle(i18n("Automatic screen rotation is disabled")); + connect(m_sni, &KStatusNotifierItem::activateRequested, this, + [this] { + m_userEnabled = !m_userEnabled; + startStopSensor(); + } + ); +} + +void OrientationSensor::startStopSensor() +{ + if (m_enabled && m_userEnabled) { + m_sensor->start(); + } else { + m_sensor->stop(); + } +} + +} diff --git a/orientation_sensor.h b/orientation_sensor.h new file mode 100644 index 0000000000..5234360c2e --- /dev/null +++ b/orientation_sensor.h @@ -0,0 +1,73 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#pragma once + +#include + +#include + +class QOrientationSensor; +class KStatusNotifierItem; + +namespace KWin +{ + +class KWIN_EXPORT OrientationSensor : public QObject +{ + Q_OBJECT +public: + explicit OrientationSensor(QObject *parent = nullptr); + ~OrientationSensor(); + + void setEnabled(bool enabled); + + /** + * Just like QOrientationReading::Orientation, + * copied to not leak the QSensors API into internal API. + **/ + enum class Orientation { + Undefined, + TopUp, + TopDown, + LeftUp, + RightUp, + FaceUp, + FaceDown + }; + + Orientation orientation() const { + return m_orientation; + } + +Q_SIGNALS: + void orientationChanged(); + +private: + void setupStatusNotifier(); + void startStopSensor(); + QOrientationSensor *m_sensor; + bool m_enabled = false; + bool m_userEnabled = true; + Orientation m_orientation = Orientation::Undefined; + KStatusNotifierItem *m_sni = nullptr; + +}; + +} diff --git a/plugins/platforms/drm/drm_object_plane.h b/plugins/platforms/drm/drm_object_plane.h index 18e74bfaa6..8ddc60c291 100644 --- a/plugins/platforms/drm/drm_object_plane.h +++ b/plugins/platforms/drm/drm_object_plane.h @@ -97,6 +97,10 @@ public: void flipBuffer(); void flipBufferWithDelete(); + Transformations supportedTransformations() const { + return m_supportedTransformations; + } + private: DrmBuffer *m_current = nullptr; DrmBuffer *m_next = nullptr; diff --git a/plugins/platforms/drm/drm_output.cpp b/plugins/platforms/drm/drm_output.cpp index 40c3fd9db9..d743f0422e 100644 --- a/plugins/platforms/drm/drm_output.cpp +++ b/plugins/platforms/drm/drm_output.cpp @@ -29,6 +29,7 @@ along with this program. If not, see . #include "logind.h" #include "logging.h" #include "main.h" +#include "orientation_sensor.h" #include "screens_drm.h" #include "wayland_server.h" // KWayland @@ -299,6 +300,15 @@ bool DrmOutput::init(drmModeConnector *connector) QString connectorName = s_connectorNames.value(connector->connector_type, QByteArrayLiteral("Unknown")); QString modelName; + m_internal = connector->connector_type == DRM_MODE_CONNECTOR_LVDS || connector->connector_type == DRM_MODE_CONNECTOR_eDP; + + if (m_internal) { + connect(kwinApp(), &Application::screensCreated, this, + [this] { + connect(screens()->orientationSensor(), &OrientationSensor::orientationChanged, this, &DrmOutput::automaticRotation); + } + ); + } if (!m_edid.monitorName.isEmpty()) { QString model = QString::fromLatin1(m_edid.monitorName); @@ -774,76 +784,7 @@ bool DrmOutput::commitChanges() } if (m_changeset->transformChanged()) { qCDebug(KWIN_DRM) << "Server setting transform: " << (int)(m_changeset->transform()); - m_waylandOutputDevice->setTransform(m_changeset->transform()); - using KWayland::Server::OutputDeviceInterface; - using KWayland::Server::OutputInterface; - switch (m_changeset->transform()) { - case OutputDeviceInterface::Transform::Normal: - if (m_primaryPlane) { - m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate0); - } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Normal); - } - m_orientation = Qt::PrimaryOrientation; - break; - case OutputDeviceInterface::Transform::Rotated90: - if (m_primaryPlane) { - m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate90); - } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Rotated90); - } - m_orientation = Qt::PortraitOrientation; - break; - case OutputDeviceInterface::Transform::Rotated180: - if (m_primaryPlane) { - m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate180); - } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Rotated180); - } - m_orientation = Qt::InvertedLandscapeOrientation; - break; - case OutputDeviceInterface::Transform::Rotated270: - if (m_primaryPlane) { - m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate270); - } - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Rotated270); - } - m_orientation = Qt::InvertedPortraitOrientation; - break; - case OutputDeviceInterface::Transform::Flipped: - // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped); - } - break; - case OutputDeviceInterface::Transform::Flipped90: - // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped90); - } - break; - case OutputDeviceInterface::Transform::Flipped180: - // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped180); - } - break; - case OutputDeviceInterface::Transform::Flipped270: - // TODO: what is this exactly? - if (m_waylandOutput) { - m_waylandOutput->setTransform(OutputInterface::Transform::Flipped270); - } - break; - } - m_modesetRequested = true; - // the cursor might need to get rotated - updateCursor(); - showCursor(); - emit modeChanged(); + transform(m_changeset->transform()); } if (m_changeset->positionChanged()) { qCDebug(KWIN_DRM) << "Server setting position: " << m_changeset->position(); @@ -857,6 +798,80 @@ bool DrmOutput::commitChanges() return true; } +void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) +{ + m_waylandOutputDevice->setTransform(transform); + using KWayland::Server::OutputDeviceInterface; + using KWayland::Server::OutputInterface; + switch (transform) { + case OutputDeviceInterface::Transform::Normal: + if (m_primaryPlane) { + m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate0); + } + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Normal); + } + m_orientation = Qt::PrimaryOrientation; + break; + case OutputDeviceInterface::Transform::Rotated90: + if (m_primaryPlane) { + m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate90); + } + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Rotated90); + } + m_orientation = Qt::PortraitOrientation; + break; + case OutputDeviceInterface::Transform::Rotated180: + if (m_primaryPlane) { + m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate180); + } + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Rotated180); + } + m_orientation = Qt::InvertedLandscapeOrientation; + break; + case OutputDeviceInterface::Transform::Rotated270: + if (m_primaryPlane) { + m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate270); + } + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Rotated270); + } + m_orientation = Qt::InvertedPortraitOrientation; + break; + case OutputDeviceInterface::Transform::Flipped: + // TODO: what is this exactly? + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Flipped); + } + break; + case OutputDeviceInterface::Transform::Flipped90: + // TODO: what is this exactly? + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Flipped90); + } + break; + case OutputDeviceInterface::Transform::Flipped180: + // TODO: what is this exactly? + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Flipped180); + } + break; + case OutputDeviceInterface::Transform::Flipped270: + // TODO: what is this exactly? + if (m_waylandOutput) { + m_waylandOutput->setTransform(OutputInterface::Transform::Flipped270); + } + break; + } + m_modesetRequested = true; + // the cursor might need to get rotated + updateCursor(); + showCursor(); + emit modeChanged(); +} + void DrmOutput::updateMode(int modeIndex) { // get all modes on the connector @@ -1196,4 +1211,56 @@ bool DrmOutput::initCursor(const QSize &cursorSize) return true; } +bool DrmOutput::supportsTransformations() const +{ + if (!m_primaryPlane) { + return false; + } + const auto transformations = m_primaryPlane->supportedTransformations(); + return transformations.testFlag(DrmPlane::Transformation::Rotate90) + || transformations.testFlag(DrmPlane::Transformation::Rotate180) + || transformations.testFlag(DrmPlane::Transformation::Rotate270); +} + +void DrmOutput::automaticRotation() +{ + if (!m_primaryPlane) { + return; + } + const auto supportedTransformations = m_primaryPlane->supportedTransformations(); + const auto requestedTransformation = screens()->orientationSensor()->orientation(); + using KWayland::Server::OutputDeviceInterface; + OutputDeviceInterface::Transform newTransformation = OutputDeviceInterface::Transform::Normal; + switch (requestedTransformation) { + case OrientationSensor::Orientation::TopUp: + newTransformation = OutputDeviceInterface::Transform::Normal; + break; + case OrientationSensor::Orientation::TopDown: + if (!supportedTransformations.testFlag(DrmPlane::Transformation::Rotate180)) { + return; + } + newTransformation = OutputDeviceInterface::Transform::Rotated180; + break; + case OrientationSensor::Orientation::LeftUp: + if (!supportedTransformations.testFlag(DrmPlane::Transformation::Rotate90)) { + return; + } + newTransformation = OutputDeviceInterface::Transform::Rotated90; + break; + case OrientationSensor::Orientation::RightUp: + if (!supportedTransformations.testFlag(DrmPlane::Transformation::Rotate270)) { + return; + } + newTransformation = OutputDeviceInterface::Transform::Rotated270; + break; + case OrientationSensor::Orientation::FaceUp: + case OrientationSensor::Orientation::FaceDown: + case OrientationSensor::Orientation::Undefined: + // unsupported + return; + } + transform(newTransformation); + emit screens()->changed(); +} + } diff --git a/plugins/platforms/drm/drm_output.h b/plugins/platforms/drm/drm_output.h index 6c4e002c3f..fa89f3b671 100644 --- a/plugins/platforms/drm/drm_output.h +++ b/plugins/platforms/drm/drm_output.h @@ -31,6 +31,8 @@ along with this program. If not, see . #include #include +#include + namespace KWayland { namespace Server @@ -110,6 +112,12 @@ public: bool initCursor(const QSize &cursorSize); + bool supportsTransformations() const; + + bool isInternal() const { + return m_internal; + } + Q_SIGNALS: void dpmsChanged(); void modeChanged(); @@ -145,6 +153,9 @@ private: bool atomicReqModesetPopulate(drmModeAtomicReq *req, bool enable); void updateMode(int modeIndex); + void transform(KWayland::Server::OutputDeviceInterface::Transform transform); + void automaticRotation(); + DrmBackend *m_backend; DrmConnector *m_conn = nullptr; DrmCrtc *m_crtc = nullptr; @@ -181,6 +192,7 @@ private: DrmDumbBuffer *m_cursor[2] = {nullptr, nullptr}; int m_cursorIndex = 0; bool m_hasNewCursor = false; + bool m_internal = false; }; } diff --git a/plugins/platforms/drm/screens_drm.cpp b/plugins/platforms/drm/screens_drm.cpp index e87d844238..b516ffca69 100644 --- a/plugins/platforms/drm/screens_drm.cpp +++ b/plugins/platforms/drm/screens_drm.cpp @@ -122,4 +122,22 @@ QSizeF DrmScreens::physicalSize(int screen) const return outputs.at(screen)->physicalSize(); } +bool DrmScreens::isInternal(int screen) const +{ + const auto outputs = m_backend->outputs(); + if (screen >= outputs.size()) { + return false; + } + return outputs.at(screen)->isInternal(); +} + +bool DrmScreens::supportsTransformations(int screen) const +{ + const auto outputs = m_backend->outputs(); + if (screen >= outputs.size()) { + return false; + } + return outputs.at(screen)->supportsTransformations(); +} + } diff --git a/plugins/platforms/drm/screens_drm.h b/plugins/platforms/drm/screens_drm.h index e7f8d961e1..608ed2331f 100644 --- a/plugins/platforms/drm/screens_drm.h +++ b/plugins/platforms/drm/screens_drm.h @@ -41,6 +41,8 @@ public: float refreshRate(int screen) const override; QSizeF physicalSize(int screen) const override; + bool isInternal(int screen) const override; + bool supportsTransformations(int screen) const override; private: DrmBackend *m_backend; diff --git a/screens.cpp b/screens.cpp index 5bf3b9939c..88eda8bc94 100644 --- a/screens.cpp +++ b/screens.cpp @@ -21,6 +21,7 @@ along with this program. If not, see . #include #include #include "cursor.h" +#include "orientation_sensor.h" #include "utils.h" #include "settings.h" #include @@ -54,7 +55,20 @@ Screens::Screens(QObject *parent) , m_current(0) , m_currentFollowsMouse(false) , m_changedTimer(new QTimer(this)) + , m_orientationSensor(new OrientationSensor(this)) { + connect(this, &Screens::changed, this, + [this] { + int internalIndex = -1; + for (int i = 0; i < m_count; i++) { + if (isInternal(i)) { + internalIndex = i; + break; + } + } + m_orientationSensor->setEnabled(internalIndex != -1 && supportsTransformations(internalIndex)); + } + ); } Screens::~Screens() @@ -195,6 +209,18 @@ QSizeF Screens::physicalSize(int screen) const return QSizeF(size(screen)) / 3.8; } +bool Screens::isInternal(int screen) const +{ + Q_UNUSED(screen) + return false; +} + +bool Screens::supportsTransformations(int screen) const +{ + Q_UNUSED(screen) + return false; +} + BasicScreens::BasicScreens(Platform *backend, QObject *parent) : Screens(parent) , m_backend(backend) diff --git a/screens.h b/screens.h index 1fbc2e6f3c..6c74b5d65e 100644 --- a/screens.h +++ b/screens.h @@ -35,6 +35,7 @@ namespace KWin { class AbstractClient; class Platform; +class OrientationSensor; class KWIN_EXPORT Screens : public QObject { @@ -124,6 +125,28 @@ public: **/ virtual QSizeF physicalSize(int screen) const; + /** + * @returns @c true if the @p screen is connected through an internal display (e.g. LVDS). + * Default implementation returns @c false. + **/ + virtual bool isInternal(int screen) const; + + /** + * @returns @c true if the @p screen can be rotated. + * Default implementation returns @c false + **/ + virtual bool supportsTransformations(int screen) const; + + /** + * Provides access to the OrientationSensor. The OrientationSensor is controlled by the + * base implementation. The implementing subclass can use this to get notifications about + * changes of the orientation and current orientation. There is no need to enable/disable it, + * that is done by the base implementation + **/ + OrientationSensor *orientationSensor() const { + return m_orientationSensor; + } + public Q_SLOTS: void reconfigure(); @@ -170,6 +193,7 @@ private: QTimer *m_changedTimer; KSharedConfig::Ptr m_config; QSize m_boundingSize; + OrientationSensor *m_orientationSensor; KWIN_SINGLETON(Screens) }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a1046a48c1..35eae423a3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -43,3 +43,6 @@ target_link_libraries(pointergestures Qt5::Gui Qt5::Quick KF5::WaylandClient) add_executable(cursorhotspottest cursorhotspottest.cpp) target_link_libraries(cursorhotspottest Qt5::Widgets) + +add_executable(orientationtest orientationtest.cpp ../orientation_sensor.cpp) +target_link_libraries(orientationtest Qt5::Widgets Qt5::Sensors KF5::Notifications KF5::I18n) diff --git a/tests/orientationtest.cpp b/tests/orientationtest.cpp new file mode 100644 index 0000000000..722043c474 --- /dev/null +++ b/tests/orientationtest.cpp @@ -0,0 +1,62 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "../orientation_sensor.h" +#include +#include + +using KWin::OrientationSensor; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + OrientationSensor sensor; + QObject::connect(&sensor, &OrientationSensor::orientationChanged, + [&sensor] { + const auto orientation = sensor.orientation(); + switch (orientation) { + case OrientationSensor::Orientation::Undefined: + qDebug() << "Undefined"; + break; + case OrientationSensor::Orientation::TopUp: + qDebug() << "TopUp"; + break; + case OrientationSensor::Orientation::TopDown: + qDebug() << "TopDown"; + break; + case OrientationSensor::Orientation::LeftUp: + qDebug() << "LeftUp"; + break; + case OrientationSensor::Orientation::RightUp: + qDebug() << "RightUp"; + break; + case OrientationSensor::Orientation::FaceUp: + qDebug() << "FaceUp"; + break; + case OrientationSensor::Orientation::FaceDown: + qDebug() << "FaceDown"; + break; + } + } + ); + sensor.setEnabled(true); + + return app.exec(); +}