mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-06-24 23:27:43 +00:00
Compare commits
10 commits
a09f349a34
...
d4da69b2f2
| Author | SHA1 | Date | |
|---|---|---|---|
| d4da69b2f2 | |||
| 53686d4ef0 | |||
| caef3bc82e | |||
| 6a1631023e | |||
| 9bf7b70d2b | |||
| acecbcc86a | |||
| aa4103f72a | |||
| 8fecdf1d2d | |||
| 276912bf31 | |||
| 0d230c5397 |
12 changed files with 73 additions and 30 deletions
|
|
@ -25,6 +25,10 @@ public:
|
||||||
{
|
{
|
||||||
KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(u"Plasma/Shell"_s);
|
KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(u"Plasma/Shell"_s);
|
||||||
pkg.setPath(u"org.kde.plasma.mobile"_s);
|
pkg.setPath(u"org.kde.plasma.mobile"_s);
|
||||||
|
if (!pkg.isValid()) {
|
||||||
|
qWarning() << "AppletHost: failed to load plasma shell package org.kde.plasma.mobile";
|
||||||
|
return;
|
||||||
|
}
|
||||||
setKPackage(pkg);
|
setKPackage(pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ public:
|
||||||
explicit AppletHost(QObject *parent = nullptr);
|
explicit AppletHost(QObject *parent = nullptr);
|
||||||
~AppletHost() override;
|
~AppletHost() override;
|
||||||
|
|
||||||
|
static QObject *create(QQmlEngine * /*engine*/, QJSEngine * /*scriptEngine*/)
|
||||||
|
{
|
||||||
|
return new AppletHost();
|
||||||
|
}
|
||||||
|
|
||||||
Q_INVOKABLE QQuickItem *fullRepresentationFor(const QString &pluginId);
|
Q_INVOKABLE QQuickItem *fullRepresentationFor(const QString &pluginId);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ MobileShell.BaseItem {
|
||||||
|
|
||||||
function delegatePressAndHold() {
|
function delegatePressAndHold() {
|
||||||
// In convergence mode, show inline detail popup if available.
|
// In convergence mode, show inline detail popup if available.
|
||||||
if (ShellSettings.Settings.convergenceModeEnabled && root.settingsCommand) {
|
if (ShellSettings.Settings.convergenceModeEnabled && root.settingsCommand && !root.restrictedPermissions) {
|
||||||
let pluginId = __appletForCommand[root.settingsCommand];
|
let pluginId = __appletForCommand[root.settingsCommand];
|
||||||
if (pluginId) {
|
if (pluginId) {
|
||||||
root.detailRequested(pluginId);
|
root.detailRequested(pluginId);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ Window {
|
||||||
readonly property real openOffset: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 3
|
readonly property real openOffset: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 3
|
||||||
readonly property int longestLength: Math.max(Screen.width, Screen.height)
|
readonly property int longestLength: Math.max(Screen.width, Screen.height)
|
||||||
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
readonly property bool isConvergence: ShellSettings.Settings.convergenceModeEnabled
|
||||||
|
// Margin between popup and screen edge in convergence mode; used in both
|
||||||
|
// the delegate x position and the input-region calculation so they stay in sync.
|
||||||
|
readonly property real convergencePopupMargin: Kirigami.Units.gridUnit * 2
|
||||||
property var keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
|
property var keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
|
||||||
|
|
||||||
LayerShell.Window.scope: "notification"
|
LayerShell.Window.scope: "notification"
|
||||||
|
|
@ -100,8 +103,8 @@ Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isConvergence) {
|
if (isConvergence) {
|
||||||
let regionX = notificationPopupManager.width - notificationPopupManager.popupWidth - Kirigami.Units.gridUnit * 4;
|
let regionX = notificationPopupManager.width - notificationPopupManager.popupWidth - notificationPopupManager.convergencePopupMargin;
|
||||||
let regionY = Screen.height - openOffset - popupHeight - Kirigami.Units.gridUnit;
|
let regionY = openOffset;
|
||||||
ShellUtil.setInputRegion(notificationPopupManager, Qt.rect(regionX, regionY, notificationPopupManager.popupWidth + Kirigami.Units.gridUnit * 2, popupHeight + Kirigami.Units.gridUnit * 2));
|
ShellUtil.setInputRegion(notificationPopupManager, Qt.rect(regionX, regionY, notificationPopupManager.popupWidth + Kirigami.Units.gridUnit * 2, popupHeight + Kirigami.Units.gridUnit * 2));
|
||||||
} else {
|
} else {
|
||||||
ShellUtil.setInputRegion(notificationPopupManager, Qt.rect((notificationPopupManager.width - notificationPopupManager.popupWidth - Kirigami.Units.gridUnit) / 2, openOffset - Kirigami.Units.gridUnit / 2, notificationPopupManager.popupWidth + Kirigami.Units.gridUnit, popupHeight + Kirigami.Units.gridUnit * ((notifications.count - notifications.currentPopupIndex > 1) ? 4 : 1)));
|
ShellUtil.setInputRegion(notificationPopupManager, Qt.rect((notificationPopupManager.width - notificationPopupManager.popupWidth - Kirigami.Units.gridUnit) / 2, openOffset - Kirigami.Units.gridUnit / 2, notificationPopupManager.popupWidth + Kirigami.Units.gridUnit, popupHeight + Kirigami.Units.gridUnit * ((notifications.count - notifications.currentPopupIndex > 1) ? 4 : 1)));
|
||||||
|
|
@ -203,7 +206,7 @@ Window {
|
||||||
id: popup
|
id: popup
|
||||||
|
|
||||||
x: notificationPopupManager.isConvergence
|
x: notificationPopupManager.isConvergence
|
||||||
? (parent.width - width - Kirigami.Units.gridUnit * 2)
|
? (parent.width - width - notificationPopupManager.convergencePopupMargin)
|
||||||
: (parent.width - width) / 2
|
: (parent.width - width) / 2
|
||||||
z: notifications.count - index
|
z: notifications.count - index
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ Item {
|
||||||
// Hover highlight in convergence mode to indicate the bar is clickable
|
// Hover highlight in convergence mode to indicate the bar is clickable
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: Qt.rgba(1.0, 1.0, 1.0, 0.1)
|
color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
|
||||||
visible: ShellSettings.Settings.convergenceModeEnabled && statusBarHover.hovered
|
visible: ShellSettings.Settings.convergenceModeEnabled && statusBarHover.hovered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#include "favouritesmodel.h"
|
#include "favouritesmodel.h"
|
||||||
#include "homescreenstate.h"
|
#include "homescreenstate.h"
|
||||||
|
|
||||||
#include <KService>
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-FileCopyrightText: Marco Allegretti
|
// SPDX-FileCopyrightText: Marco Allegretti
|
||||||
// SPDX-License-Identifier: EUPL 1.2
|
// SPDX-License-Identifier: EUPL-1.2
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as QQC2
|
import QtQuick.Controls as QQC2
|
||||||
|
|
@ -179,7 +179,27 @@ Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
activeFocusOnTab: true
|
||||||
onClicked: root.categorySelected(tile.catId)
|
onClicked: root.categorySelected(tile.catId)
|
||||||
|
|
||||||
|
Keys.onPressed: (event) => {
|
||||||
|
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_Space) {
|
||||||
|
root.categorySelected(tile.catId);
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible.role: Accessible.Button
|
||||||
|
Accessible.name: tile.catName
|
||||||
|
Accessible.onPressAction: root.categorySelected(tile.catId)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
border.color: Kirigami.Theme.highlightColor
|
||||||
|
border.width: tileArea.activeFocus ? 2 : 0
|
||||||
|
radius: parent.parent.radius
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -642,12 +642,12 @@ MouseArea {
|
||||||
x: {
|
x: {
|
||||||
if (!targetDelegate) return 0
|
if (!targetDelegate) return 0
|
||||||
var delegateGlobal = targetDelegate.mapToGlobal(0, 0)
|
var delegateGlobal = targetDelegate.mapToGlobal(0, 0)
|
||||||
return Math.max(0, delegateGlobal.x + (targetDelegate.width - width) / 2)
|
return Math.max(0, Math.min(Screen.width - width, delegateGlobal.x + (targetDelegate.width - width) / 2))
|
||||||
}
|
}
|
||||||
y: {
|
y: {
|
||||||
if (!targetDelegate) return 0
|
if (!targetDelegate) return 0
|
||||||
var delegateGlobal = targetDelegate.mapToGlobal(0, 0)
|
var delegateGlobal = targetDelegate.mapToGlobal(0, 0)
|
||||||
return delegateGlobal.y - height - Kirigami.Units.smallSpacing
|
return Math.max(0, Math.min(Screen.height - height, delegateGlobal.y - height - Kirigami.Units.smallSpacing))
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
|
|
@ -916,7 +916,7 @@ MouseArea {
|
||||||
Repeater {
|
Repeater {
|
||||||
model: {
|
model: {
|
||||||
var ids = taskDelegate.model.WinIdList
|
var ids = taskDelegate.model.WinIdList
|
||||||
return ids ? ids.length : 1
|
return Math.max(1, ids ? ids.length : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,6 @@ MobileShell.NavigationPanel {
|
||||||
foregroundColorGroup: forcedComplementary ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
|
foregroundColorGroup: forcedComplementary ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
|
||||||
shadow: forcedComplementary
|
shadow: forcedComplementary
|
||||||
|
|
||||||
// Convergence mode: expose running-app task strip
|
|
||||||
convergenceMode: ShellSettings.Settings.convergenceModeEnabled
|
|
||||||
taskModel: tasksModel
|
|
||||||
virtualDesktopInfo: virtualDesktopInfo
|
|
||||||
|
|
||||||
MobileShellState.PanelSettingsDBusClient {
|
MobileShellState.PanelSettingsDBusClient {
|
||||||
id: panelSettings
|
id: panelSettings
|
||||||
screenName: Screen.name
|
screenName: Screen.name
|
||||||
|
|
@ -75,22 +70,18 @@ MobileShell.NavigationPanel {
|
||||||
// ~~~~
|
// ~~~~
|
||||||
// navigation panel actions
|
// navigation panel actions
|
||||||
|
|
||||||
// toggle task switcher button (KWin Overview in convergence mode, mobile task switcher otherwise)
|
// toggle task switcher button
|
||||||
leftAction: MobileShell.NavigationPanelAction {
|
leftAction: MobileShell.NavigationPanelAction {
|
||||||
id: taskSwitcherAction
|
id: taskSwitcherAction
|
||||||
|
|
||||||
enabled: true
|
enabled: true
|
||||||
iconSource: ShellSettings.Settings.convergenceModeEnabled ? "view-grid-symbolic" : "mobile-task-switcher"
|
iconSource: "mobile-task-switcher"
|
||||||
shrinkSize: ShellSettings.Settings.convergenceModeEnabled ? 0 : 4
|
shrinkSize: 4
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (ShellSettings.Settings.convergenceModeEnabled) {
|
|
||||||
Plasmoid.triggerOverview();
|
|
||||||
} else {
|
|
||||||
Plasmoid.triggerTaskSwitcher();
|
Plasmoid.triggerTaskSwitcher();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// home button
|
// home button
|
||||||
middleAction: MobileShell.NavigationPanelAction {
|
middleAction: MobileShell.NavigationPanelAction {
|
||||||
|
|
|
||||||
|
|
@ -158,13 +158,13 @@ ContainmentItem {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
|
flags: Qt.FramelessWindowHint | Qt.WindowTransparentForInput
|
||||||
// height is set by layer-shell anchoring; provide a fallback.
|
// height is set by layer-shell anchoring; provide a fallback.
|
||||||
height: root.navigationPanelHeight
|
height: Kirigami.Units.gridUnit * 3
|
||||||
width: 1 // layer-shell stretches it via AnchorLeft|AnchorRight
|
width: 1 // layer-shell stretches it via AnchorLeft|AnchorRight
|
||||||
|
|
||||||
LayerShell.Window.scope: "dock-space"
|
LayerShell.Window.scope: "dock-space"
|
||||||
LayerShell.Window.layer: LayerShell.Window.LayerBottom
|
LayerShell.Window.layer: LayerShell.Window.LayerBottom
|
||||||
LayerShell.Window.anchors: LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
|
LayerShell.Window.anchors: LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
|
||||||
LayerShell.Window.exclusionZone: root.navigationPanelHeight
|
LayerShell.Window.exclusionZone: Kirigami.Units.gridUnit * 3
|
||||||
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
|
LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Loader {
|
||||||
|
|
||||||
const output = window.output
|
const output = window.output
|
||||||
const desktop = window.desktops[0]
|
const desktop = window.desktops[0]
|
||||||
|
if (!output) return
|
||||||
if (!desktop) return
|
if (!desktop) return
|
||||||
|
|
||||||
const maxRect = KWinComponents.Workspace.clientArea(
|
const maxRect = KWinComponents.Workspace.clientArea(
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,33 @@ public Q_SLOTS:
|
||||||
|
|
||||||
KAuth::ActionReply Flashlighthelper::setbrightness(const QVariantMap &args)
|
KAuth::ActionReply Flashlighthelper::setbrightness(const QVariantMap &args)
|
||||||
{
|
{
|
||||||
const char *sysPath = args.value("sysPath"_L1).toString().toUtf8().constData();
|
// Store as named QByteArrays so constData() pointers remain valid for the
|
||||||
const char *brightness = args.value("brightness"_L1).toString().toUtf8().constData();
|
// duration of the function. The originals were temporaries that were
|
||||||
|
// destroyed at the end of each declaration statement.
|
||||||
|
// (need to double-check this, but seems likely to be the cause of the random failures
|
||||||
|
// we were seeing in testing)
|
||||||
|
const QByteArray sysPathBytes = args.value("sysPath"_L1).toString().toUtf8();
|
||||||
|
QByteArray brightnessBytes = args.value("brightness"_L1).toString().toUtf8();
|
||||||
|
|
||||||
|
if (sysPathBytes.isEmpty()) {
|
||||||
|
qCWarning(FLASHLIGHTHELPER) << "sysPath argument is missing or empty";
|
||||||
|
return KAuth::ActionReply::HelperErrorReply();
|
||||||
|
}
|
||||||
|
|
||||||
struct udev *udev = udev_new();
|
struct udev *udev = udev_new();
|
||||||
struct udev_device *device = udev_device_new_from_syspath(udev, sysPath);
|
if (!udev) {
|
||||||
|
qCWarning(FLASHLIGHTHELPER) << "Failed to create udev context";
|
||||||
|
return KAuth::ActionReply::HelperErrorReply();
|
||||||
|
}
|
||||||
|
|
||||||
int ret = udev_device_set_sysattr_value(device, "brightness", const_cast<char *>(brightness));
|
struct udev_device *device = udev_device_new_from_syspath(udev, sysPathBytes.constData());
|
||||||
|
if (!device) {
|
||||||
|
qCWarning(FLASHLIGHTHELPER) << "Failed to find udev device for syspath:" << sysPathBytes;
|
||||||
|
udev_unref(udev);
|
||||||
|
return KAuth::ActionReply::HelperErrorReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = udev_device_set_sysattr_value(device, "brightness", brightnessBytes.data());
|
||||||
|
|
||||||
udev_device_unref(device);
|
udev_device_unref(device);
|
||||||
udev_unref(udev);
|
udev_unref(udev);
|
||||||
|
|
@ -42,7 +62,7 @@ KAuth::ActionReply Flashlighthelper::setbrightness(const QVariantMap &args)
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
return KAuth::ActionReply::SuccessReply();
|
return KAuth::ActionReply::SuccessReply();
|
||||||
} else {
|
} else {
|
||||||
qCWarning(FLASHLIGHTHELPER) << "Failed to set udev system attribute";
|
qCWarning(FLASHLIGHTHELPER) << "Failed to set udev system attribute, errno:" << -ret;
|
||||||
return KAuth::ActionReply::HelperErrorReply();
|
return KAuth::ActionReply::HelperErrorReply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue