Commit 36cf7aed authored by David Redondo's avatar David Redondo 🏎
Browse files

osd: Port to layer shell

Ports the OSD window Layershell. Instead of a Plasma Dialog
a QQuickView is now used as a window that hosts the contents.
parent cb4dd3b1
......@@ -22,3 +22,4 @@ Dependencies:
'frameworks/plasma-framework': '@latest'
'frameworks/kcmutils': '@latest'
'plasma/libkscreen': '@same'
'plasma/layer-shell-qt': '@same'
......@@ -54,6 +54,15 @@ set_package_properties(X11 PROPERTIES
TYPE REQUIRED
)
find_package(LayerShellQt)
set_package_properties(LayerShellQt PROPERTIES
DESCRIPTION "Layer shell Qt bindings"
URL "https://invent.kde.org/plasma/layer-shell-qt"
PURPOSE "Required for the screen selection osd"
TYPE REQUIRED
)
if(X11_FOUND)
set(HAVE_X11 1)
find_package(X11_XCB REQUIRED)
......
......@@ -3,7 +3,14 @@ add_executable(kscreen_osd_service main.cpp osdmanager.cpp osd.cpp ../common/osd
qt_add_dbus_adaptor(DBUS_SRC org.kde.kscreen.osdService.xml osdmanager.h KScreen::OsdManager)
target_sources(kscreen_osd_service PRIVATE ${DBUS_SRC})
target_link_libraries(kscreen_osd_service PRIVATE Qt::DBus KF5::Declarative KF5::I18n KF5::Screen)
target_link_libraries(kscreen_osd_service PRIVATE
Qt::DBus
Qt::Quick
KF5::I18n
KF5::WindowSystem
KF5::Screen
LayerShellQt::Interface
)
set(QML_FILES
qml/OsdSelector.qml
......
......@@ -4,6 +4,8 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <LayerShellQt/Shell>
#include <QGuiApplication>
#include "osdmanager.h"
......@@ -11,5 +13,6 @@
int main(int argc, char **argv)
{
KScreen::OsdManager osdManager;
LayerShellQt::Shell::useLayerShell();
return QGuiApplication(argc, argv).exec();
}
......@@ -11,13 +11,18 @@
#include <KScreen/Mode>
#include <LayerShellQt/Window>
#include <KWindowSystem>
#include <QCursor>
#include <QGuiApplication>
#include <QQuickItem>
#include <QScreen>
#include <QStandardPaths>
#include <QTimer>
#include <KDeclarative/QmlObjectSharedEngine>
#include <QQuickView>
using namespace KScreen;
......@@ -42,29 +47,35 @@ void Osd::showActionSelector()
qWarning() << "Failed to find action selector OSD QML file" << osdPath;
return;
}
m_osdActionSelector = new KDeclarative::QmlObjectSharedEngine(this);
m_osdActionSelector = std::make_unique<QQuickView>(&m_engine, nullptr);
m_osdActionSelector->setInitialProperties({{QLatin1String("actions"), QVariant::fromValue(OsdAction::availableActions())}});
m_osdActionSelector->setSource(QUrl::fromLocalFile(osdPath));
m_osdActionSelector->setColor(Qt::transparent);
m_osdActionSelector->setFlag(Qt::FramelessWindowHint);
if (m_osdActionSelector->status() != QQmlComponent::Ready) {
if (m_osdActionSelector->status() != QQuickView::Ready) {
qWarning() << "Failed to load OSD QML file" << osdPath;
delete m_osdActionSelector;
m_osdActionSelector = nullptr;
m_osdActionSelector.reset();
return;
}
auto *rootObject = m_osdActionSelector->rootObject();
auto rootObject = m_osdActionSelector->rootObject();
connect(rootObject, SIGNAL(clicked(int)), this, SLOT(onOsdActionSelected(int)));
}
if (auto *rootObject = m_osdActionSelector->rootObject()) {
// On wayland, we use m_output to set an action on OSD position
if (qGuiApp->platformName() == QLatin1String("wayland")) {
rootObject->setProperty("screenGeometry", m_output->geometry());
}
rootObject->setProperty("visible", true);
rootObject->setProperty("actions", QVariant::fromValue(OsdAction::availableActions()));
if (KWindowSystem::isPlatformWayland()) {
auto layerWindow = LayerShellQt::Window::get(m_osdActionSelector.get());
layerWindow->setLayer(LayerShellQt::Window::LayerOverlay);
layerWindow->setAnchors({});
layerWindow->setDesiredOutput(qGuiApp->screenAt(m_output->pos()));
} else {
qWarning() << "Could not get root object for action selector.";
auto newGeometry = m_osdActionSelector->geometry();
newGeometry.moveCenter(m_output->geometry().center());
m_osdActionSelector->setGeometry(newGeometry);
KWindowSystem::setState(m_osdActionSelector->winId(), NET::SkipPager | NET::SkipSwitcher | NET::SkipTaskbar);
m_osdActionSelector->requestActivate();
}
m_osdActionSelector->setVisible(true);
}
void Osd::onOsdActionSelected(int action)
......@@ -83,8 +94,6 @@ void Osd::onOutputAvailabilityChanged()
void Osd::hideOsd()
{
if (m_osdActionSelector) {
if (auto *rootObject = m_osdActionSelector->rootObject()) {
rootObject->setProperty("visible", false);
}
m_osdActionSelector->setVisible(false);
}
}
......@@ -9,11 +9,14 @@
#define KSCREEN_OSD_H
#include <QObject>
#include <QQmlEngine>
#include <QRect>
#include <QString>
#include <KScreen/Output>
#include <memory>
#include "osdmanager.h"
namespace KDeclarative
......@@ -21,6 +24,8 @@ namespace KDeclarative
class QmlObject;
}
class QQuickView;
class QTimer;
namespace KScreen
......@@ -49,8 +54,8 @@ private:
bool initOsd();
KScreen::OutputPtr m_output;
QRect m_outputGeometry;
KDeclarative::QmlObject *m_osdActionSelector = nullptr;
QQmlEngine m_engine;
std::unique_ptr<QQuickView> m_osdActionSelector;
QTimer *m_osdTimer = nullptr;
int m_timeout = 0;
};
......
......@@ -4,8 +4,8 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.10
import org.kde.plasma.core 2.0 as PlasmaCore
......@@ -14,22 +14,19 @@ import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.KScreen 1.0
PlasmaCore.Dialog {
Control {
id: root
location: PlasmaCore.Types.Floating
type: PlasmaCore.Dialog.Normal
property string infoText
property var screenGeometry
property var actions
onScreenGeometryChanged: {
root.x = screenGeometry.x + (screenGeometry.width - mainItem.width) / 2
root.y = screenGeometry.y + (screenGeometry.height - mainItem.height) / 2
}
signal clicked(int actionId)
mainItem: ColumnLayout {
leftPadding: shadow.margins.left + background.margins.left
rightPadding: shadow.margins.right + background.margins.right
topPadding: shadow.margins.top + background.margins.top
bottomPadding: shadow.margins.bottom + background.margins.bottom
contentItem : ColumnLayout {
RowLayout {
Repeater {
id: actionRepeater
......@@ -118,4 +115,20 @@ PlasmaCore.Dialog {
}
}
}
background: PlasmaCore.FrameSvgItem {
id: shadow
imagePath: "dialogs/background"
prefix: "shadow"
PlasmaCore.FrameSvgItem {
id: background
anchors.leftMargin: shadow.margins.left
anchors.rightMargin: shadow.margins.right
anchors.topMargin: shadow.margins.top
anchors.bottomMargin: shadow.margins.bottom
anchors.fill: parent
imagePath: "solid/dialogs/background"
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment