mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
navigationpanel: Add manual screen rotation button
When the device is rotated and autorotate is off, a button will appear on the navigation panel to manually rotate. This is specific to the navigation panel, perhaps we can have a floating button in gesture-only mode similar to Android? TODO: PoC, I haven't yet actually tested this on device. I also need to make sure that I check for whether autorotation is enabled on the output.
This commit is contained in:
parent
aa3e42f65a
commit
3d9ddbde15
5 changed files with 188 additions and 0 deletions
|
|
@ -54,6 +54,21 @@ Item {
|
|||
color: root.backgroundColor
|
||||
}
|
||||
|
||||
NavigationPanelButton {
|
||||
id: leftCornerButton
|
||||
visible: root.leftCornerAction.visible
|
||||
Kirigami.Theme.colorSet: root.foregroundColorGroup
|
||||
Kirigami.Theme.inherit: false
|
||||
enabled: root.leftCornerAction.enabled
|
||||
iconSizeFactor: root.leftCornerAction.iconSizeFactor
|
||||
iconSource: root.leftCornerAction.iconSource
|
||||
onClicked: {
|
||||
if (enabled) {
|
||||
root.leftCornerAction.triggered();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// button row (anchors provided by state)
|
||||
NavigationPanelButton {
|
||||
id: leftButton
|
||||
|
|
@ -166,6 +181,18 @@ Item {
|
|||
height: Kirigami.Units.gridUnit * 2
|
||||
width: icons.width
|
||||
}
|
||||
AnchorChanges {
|
||||
target: leftCornerButton
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
PropertyChanges {
|
||||
target: leftCornerButton
|
||||
height: Kirigami.Units.gridUnit * 2
|
||||
width: icons.width
|
||||
}
|
||||
}, State {
|
||||
name: "horizontal"
|
||||
when: !root.isVertical
|
||||
|
|
@ -214,6 +241,18 @@ Item {
|
|||
height: parent.height
|
||||
width: Kirigami.Units.gridUnit * 2
|
||||
}
|
||||
AnchorChanges {
|
||||
target: leftCornerButton
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
}
|
||||
}
|
||||
PropertyChanges {
|
||||
target: leftCornerButton
|
||||
height: parent.height
|
||||
width: Kirigami.Units.gridUnit * 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ target_link_libraries(org.kde.plasma.mobile.taskpanel
|
|||
Qt::DBus
|
||||
Qt::Qml
|
||||
Qt::Quick
|
||||
Qt::Sensors
|
||||
Plasma::Plasma
|
||||
KF6::Screen
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,18 @@ MobileShell.NavigationPanel {
|
|||
}
|
||||
}
|
||||
|
||||
leftCornerAction: MobileShell.NavigationPanelAction {
|
||||
id: rotationAction
|
||||
visible: Plasmoid.showRotationButton
|
||||
enabled: true
|
||||
iconSource: "rotation-allowed-symbolic"
|
||||
iconSizeFactor: 0.75
|
||||
|
||||
onTriggered: {
|
||||
Plasmoid.rotateToSuggestedRotation();
|
||||
}
|
||||
}
|
||||
|
||||
rightCornerAction: MobileShell.NavigationPanelAction {
|
||||
id: keyboardToggleAction
|
||||
visible: ShellSettings.Settings.alwaysShowKeyboardToggleOnNavigationPanel ||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,54 @@
|
|||
#include <QDebug>
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <kscreen/configmonitor.h>
|
||||
#include <kscreen/getconfigoperation.h>
|
||||
#include <kscreen/output.h>
|
||||
#include <kscreen/setconfigoperation.h>
|
||||
|
||||
// register type for Keyboards.KWinVirtualKeyboard.forceActivate();
|
||||
Q_DECLARE_METATYPE(QDBusPendingReply<>)
|
||||
|
||||
KScreen::Output::Rotation mapReadingOrientation(QOrientationReading::Orientation orientation)
|
||||
{
|
||||
switch (orientation) {
|
||||
case QOrientationReading::Orientation::TopUp:
|
||||
return KScreen::Output::Rotation::None;
|
||||
case QOrientationReading::Orientation::TopDown:
|
||||
return KScreen::Output::Rotation::Inverted;
|
||||
case QOrientationReading::Orientation::LeftUp:
|
||||
return KScreen::Output::Rotation::Left;
|
||||
case QOrientationReading::Orientation::RightUp:
|
||||
return KScreen::Output::Rotation::Right;
|
||||
case QOrientationReading::Orientation::FaceUp:
|
||||
case QOrientationReading::Orientation::FaceDown:
|
||||
case QOrientationReading::Orientation::Undefined:
|
||||
return KScreen::Output::Rotation::None;
|
||||
}
|
||||
return KScreen::Output::Rotation::None;
|
||||
}
|
||||
|
||||
TaskPanel::TaskPanel(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
|
||||
: Plasma::Containment(parent, data, args)
|
||||
, m_sensor{new QOrientationSensor(this)}
|
||||
{
|
||||
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, [this](auto *op) {
|
||||
m_config = qobject_cast<KScreen::GetConfigOperation *>(op)->config();
|
||||
KScreen::ConfigMonitor::instance()->addConfig(m_config);
|
||||
|
||||
// update all screens with event connect
|
||||
for (KScreen::OutputPtr output : m_config->outputs()) {
|
||||
connect(output.data(), &KScreen::Output::autoRotatePolicyChanged, this, &TaskPanel::updateShowRotationButton);
|
||||
}
|
||||
|
||||
// listen to all new screens and connect
|
||||
connect(m_config.data(), &KScreen::Config::outputAdded, this, [this](const auto &output) {
|
||||
connect(output.data(), &KScreen::Output::autoRotatePolicyChanged, this, &TaskPanel::updateShowRotationButton);
|
||||
});
|
||||
});
|
||||
|
||||
connect(m_sensor, &QOrientationSensor::readingChanged, this, &TaskPanel::updateShowRotationButton);
|
||||
m_sensor->start();
|
||||
}
|
||||
|
||||
void TaskPanel::triggerTaskSwitcher() const
|
||||
|
|
@ -28,6 +70,79 @@ void TaskPanel::triggerTaskSwitcher() const
|
|||
QDBusConnection::sessionBus().send(message);
|
||||
}
|
||||
|
||||
void TaskPanel::rotateToSuggestedRotation()
|
||||
{
|
||||
if (!m_config || !m_showRotationButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto outputs = m_config->outputs();
|
||||
if (outputs.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// HACK: Assume the output we care about is the first device
|
||||
for (KScreen::OutputPtr output : outputs) {
|
||||
// apparently it's possible to get nullptr outputs?
|
||||
if (!output) {
|
||||
continue;
|
||||
}
|
||||
|
||||
output->setRotation(m_rotateTo);
|
||||
}
|
||||
|
||||
auto setop = new KScreen::SetConfigOperation(m_config, this);
|
||||
setop->exec();
|
||||
|
||||
updateShowRotationButton();
|
||||
}
|
||||
|
||||
bool TaskPanel::showRotationButton() const
|
||||
{
|
||||
return m_showRotationButton;
|
||||
}
|
||||
|
||||
void TaskPanel::updateShowRotationButton()
|
||||
{
|
||||
if (!m_config) {
|
||||
return;
|
||||
}
|
||||
|
||||
QOrientationReading *reading = m_sensor->reading();
|
||||
if (!reading) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_rotateTo = mapReadingOrientation(reading->orientation());
|
||||
|
||||
const auto outputs = m_config->outputs();
|
||||
|
||||
if (outputs.empty()) {
|
||||
m_showRotationButton = false;
|
||||
Q_EMIT showRotationButtonChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
// HACK: Assume the output we care about is the first device
|
||||
for (KScreen::OutputPtr output : outputs) {
|
||||
if (!output) {
|
||||
// apparently it's possible to get nullptr outputs?
|
||||
continue;
|
||||
}
|
||||
if (output->autoRotatePolicy() == KScreen::Output::AutoRotatePolicy::Always) {
|
||||
// only check displays that have autorotate on
|
||||
continue;
|
||||
}
|
||||
|
||||
m_showRotationButton = output->rotation() != m_rotateTo;
|
||||
Q_EMIT showRotationButtonChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
m_showRotationButton = false;
|
||||
Q_EMIT showRotationButtonChanged();
|
||||
}
|
||||
|
||||
K_PLUGIN_CLASS(TaskPanel)
|
||||
|
||||
#include "taskpanel.moc"
|
||||
|
|
|
|||
|
|
@ -7,13 +7,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <Plasma/Containment>
|
||||
#include <QOrientationSensor>
|
||||
|
||||
#include <kscreen/config.h>
|
||||
|
||||
class TaskPanel : public Plasma::Containment
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool showRotationButton READ showRotationButton NOTIFY showRotationButtonChanged)
|
||||
|
||||
public:
|
||||
TaskPanel(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
|
||||
|
||||
Q_INVOKABLE void triggerTaskSwitcher() const;
|
||||
|
||||
bool showRotationButton() const;
|
||||
Q_INVOKABLE void rotateToSuggestedRotation();
|
||||
|
||||
Q_SIGNALS:
|
||||
void showRotationButtonChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateShowRotationButton();
|
||||
|
||||
private:
|
||||
bool m_showRotationButton{false};
|
||||
KScreen::Output::Rotation m_rotateTo;
|
||||
|
||||
KScreen::ConfigPtr m_config{nullptr};
|
||||
QOrientationSensor *m_sensor{nullptr};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue