Rename all to Breezy

This commit is contained in:
wheaney 2025-07-03 15:31:02 -07:00
parent faf35e0cd4
commit 47e5fe5e01
14 changed files with 138 additions and 314 deletions

View File

@ -1,111 +0,0 @@
# Cube effect
![Screenshot](data/screenshot.avif)
This is a basic desktop cube effect for KWin. It's primarily intended to help you
impress your friends with what one can do on "Linux."
<p align="center">
<img src="https://raw.githubusercontent.com/zzag/kwin-effects-cube/main/data/demo.gif" />
</p>
## How to use it
Go to desktop effect settings, and enable the Cube effect. Once you've done that,
the Cube effect can be activated by pressing `Meta+C` shortcut.
Note that you will need at least 3 virtual desktops in order to activate the effect.
Key navigation:
- `Escape` - quit the effect
- `Left` and `Right` arrow keys - rotate the cube left or right, respectively
- `Enter`/`Space`/`Return` - switch to the currently viewed desktop
Mouse navigation:
- LMB click - switch to the currently viewed desktop
- Press LMB and drag - rotate the cube
- Wheel up and down - move the cube farther or closer, respectively
## Installation
Arch Linux:
For users who are using KF6/Plasma 6
```sh
yay -S kwin-effects-cube-git
```
For users who are using Plasma 5
```sh
yay -S kwin-effects-cube
```
## Building from Git
You will need the following dependencies to build this effect:
* CMake
* any C++14 enabled compiler
* Qt
- qtbase
- qtdeclarative
- qtquick3d
* libkwineffects
* KDE Frameworks 5:
- Config
- CoreAddons
- Extra CMake Modules
- GlobalAccel
- WindowSystem
On Arch Linux
```sh
sudo pacman -S cmake extra-cmake-modules kwin qt5-quick3d
```
On Fedora
```sh
sudo dnf install cmake extra-cmake-modules kf5-kconfig-devel kf5-kcoreaddons-devel \
kf5-kglobalaccel-devel kf5-ki18n-devel kf5-kwindowsystem-devel kf5-kxmlgui-devel \
kwin-devel libepoxy-devel qt5-qtbase-devel
```
On Ubuntu
```sh
sudo apt install cmake extra-cmake-modules gettext kwin-dev libkf5config-dev \
libkf5configwidgets-dev libkf5coreaddons-dev libkf5globalaccel-dev
libkf5windowsystem-dev libkf5xmlgui-dev qtbase5-dev qtdeclarative5-dev
```
After you installed all the required dependencies, you can build
the effect:
```sh
git clone https://github.com/zzag/kwin-effects-cube.git
cd kwin-effects-cube
cmake -B build -S . \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr
cmake --build build --parallel
cmake --install build
```
## Building QtQuick 3D from source code
Note that some distributions (e.g. Ubuntu or Fedora) don't package QtQuick 3D.
If you use such a distro, you will have to build QtQuick 3D from source code.
Go to https://download.qt.io/official_releases/qt/ and download qtquick3d source
tarball (it's in `submodules/` folder) for 5.15, unpack it and run the following commands
```
qmake qtquick3d.pro
make
make install
```

View File

@ -1,10 +1,6 @@
# SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
#
# SPDX-License-Identifier: BSD-3-Clause
kcoreaddons_add_plugin(breezy_desktop_effect INSTALL_NAMESPACE "kwin/effects/plugins/")
target_sources(breezy_desktop_effect PRIVATE
cubeeffect.cpp
breezydesktopeffect.cpp
main.cpp
)
@ -22,4 +18,4 @@ target_link_libraries(breezy_desktop_effect
KWin::kwin
)
install(DIRECTORY qml DESTINATION ${KDE_INSTALL_DATADIR}/kwin/effects/cube)
install(DIRECTORY qml DESTINATION ${KDE_INSTALL_DATADIR}/kwin/effects/breezy_desktop)

View File

@ -1,2 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT `find . -name \*.qml-o -name \*.cpp` -o $podir/kwin_effect_cube.pot
$XGETTEXT `find . -name \*.qml-o -name \*.cpp` -o $podir/kwin_effect_breezy_desktop.pot

View File

@ -1,10 +1,4 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "cubeeffect.h"
#include "breezydesktopeffect.h"
#include "effect/effect.h"
#include "effect/effecthandler.h"
@ -22,41 +16,43 @@ Q_LOGGING_CATEGORY(KWIN_XR, "kwin.xr")
namespace KWin
{
CubeEffect::CubeEffect()
BreezyDesktopEffect::BreezyDesktopEffect()
: m_shutdownTimer(new QTimer(this))
{
qCCritical(KWIN_XR) << "\t\t\tBreezy - constructor";
qmlRegisterUncreatableType<CubeEffect>("org.kde.kwin.effect.cube", 1, 0, "CubeEffect", QStringLiteral("Cube cannot be created in QML"));
qmlRegisterUncreatableType<BreezyDesktopEffect>("org.kde.kwin.effect.breezy_desktop", 1, 0, "BreezyDesktopEffect", QStringLiteral("BreezyDesktop cannot be created in QML"));
m_shutdownTimer->setSingleShot(true);
connect(m_shutdownTimer, &QTimer::timeout, this, &CubeEffect::realDeactivate);
connect(effects, &EffectsHandler::screenAboutToLock, this, &CubeEffect::realDeactivate);
connect(m_shutdownTimer, &QTimer::timeout, this, &BreezyDesktopEffect::realDeactivate);
connect(effects, &EffectsHandler::screenAboutToLock, this, &BreezyDesktopEffect::realDeactivate);
const QKeySequence defaultToggleShortcut = Qt::META | Qt::Key_C;
const QKeySequence defaultToggleShortcut = Qt::META | Qt::Key_B;
m_toggleAction = new QAction(this);
m_toggleAction->setObjectName(QStringLiteral("Cube"));
m_toggleAction->setText(i18n("Toggle Cube"));
m_toggleAction->setObjectName(QStringLiteral("BreezyDesktop"));
m_toggleAction->setText(i18n("Toggle BreezyDesktop"));
KGlobalAccel::self()->setDefaultShortcut(m_toggleAction, {defaultToggleShortcut});
KGlobalAccel::self()->setShortcut(m_toggleAction, {defaultToggleShortcut});
m_toggleShortcut = KGlobalAccel::self()->shortcut(m_toggleAction);
connect(m_toggleAction, &QAction::triggered, this, &CubeEffect::toggle);
connect(m_toggleAction, &QAction::triggered, this, &BreezyDesktopEffect::toggle);
connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged, this, [this](QAction *action, const QKeySequence &seq) {
if (action->objectName() == QStringLiteral("Cube")) {
if (action->objectName() == QStringLiteral("BreezyDesktop")) {
m_toggleShortcut.clear();
m_toggleShortcut.append(seq);
}
});
setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/cube/qml/main.qml"))));
setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/breezy_desktop/qml/main.qml"))));
m_xrRotationTimer = new QTimer(this);
m_xrRotationTimer->setInterval(16); // ~60Hz
connect(m_xrRotationTimer, &QTimer::timeout, this, &CubeEffect::updateXrRotation);
connect(m_xrRotationTimer, &QTimer::timeout, this, &BreezyDesktopEffect::updateXrRotation);
m_xrRotationTimer->start();
toggle();
}
QVariantMap CubeEffect::initialProperties(Output *screen)
QVariantMap BreezyDesktopEffect::initialProperties(Output *screen)
{
return QVariantMap{
{QStringLiteral("effect"), QVariant::fromValue(this)},
@ -64,32 +60,12 @@ QVariantMap CubeEffect::initialProperties(Output *screen)
};
}
int CubeEffect::requestedEffectChainPosition() const
int BreezyDesktopEffect::requestedEffectChainPosition() const
{
return 70;
}
void CubeEffect::grabbedKeyboardEvent(QKeyEvent *e)
{
if (e->type() == QEvent::KeyPress) {
if (m_toggleShortcut.contains(e->key() | e->modifiers())) {
toggle();
return;
}
}
QuickSceneEffect::grabbedKeyboardEvent(e);
}
bool CubeEffect::borderActivated(ElectricBorder border)
{
if (m_borderActivate.contains(border)) {
toggle();
return true;
}
return false;
}
void CubeEffect::toggle()
void BreezyDesktopEffect::toggle()
{
if (isRunning()) {
deactivate();
@ -99,7 +75,7 @@ void CubeEffect::toggle()
}
}
void CubeEffect::activate()
void BreezyDesktopEffect::activate()
{
if (effects->isScreenLocked()) {
return;
@ -114,7 +90,7 @@ void CubeEffect::activate()
effects->stopMouseInterception(this);
}
void CubeEffect::deactivate()
void BreezyDesktopEffect::deactivate()
{
if (m_shutdownTimer->isActive()) {
return;
@ -130,51 +106,51 @@ void CubeEffect::deactivate()
m_shutdownTimer->start(animationDuration());
}
void CubeEffect::realDeactivate()
void BreezyDesktopEffect::realDeactivate()
{
setRunning(false);
}
int CubeEffect::animationDuration() const
int BreezyDesktopEffect::animationDuration() const
{
return 200;
}
qreal CubeEffect::cubeFaceDisplacement() const
qreal BreezyDesktopEffect::faceDisplacement() const
{
return 100;
}
qreal CubeEffect::distanceFactor() const
qreal BreezyDesktopEffect::distanceFactor() const
{
return 1.5;
}
bool CubeEffect::mouseInvertedX() const
bool BreezyDesktopEffect::mouseInvertedX() const
{
return false;
}
bool CubeEffect::mouseInvertedY() const
bool BreezyDesktopEffect::mouseInvertedY() const
{
return false;
}
CubeEffect::BackgroundMode CubeEffect::backgroundMode() const
BreezyDesktopEffect::BackgroundMode BreezyDesktopEffect::backgroundMode() const
{
return BackgroundMode::Color;
}
QColor CubeEffect::backgroundColor() const
QColor BreezyDesktopEffect::backgroundColor() const
{
return QColor(Qt::black);
}
QQuaternion CubeEffect::xrRotation() const {
QQuaternion BreezyDesktopEffect::xrRotation() const {
return m_xrRotation;
}
void CubeEffect::updateXrRotation() {
void BreezyDesktopEffect::updateXrRotation() {
const QString shmPath = QStringLiteral("/dev/shm/breezy_desktop_imu");
QFile shmFile(shmPath);
@ -219,6 +195,11 @@ void CubeEffect::updateXrRotation() {
const bool enabled = (enabledFlag != 0) && (version == expectedVersion) && validData;
if (!enabled) {
if (isRunning()) {
qCCritical(KWIN_XR) << "\t\t\tBreezy - deactivate due to disabled";
deactivate();
}
return;
}
@ -227,6 +208,11 @@ void CubeEffect::updateXrRotation() {
imuData[2] == 0.0f && imuData[3] == 1.0f);
if (imuResetState) {
if (isRunning()) {
qCCritical(KWIN_XR) << "\t\t\tBreezy - deactivate due to reset state";
deactivate();
}
return;
}
@ -235,6 +221,12 @@ void CubeEffect::updateXrRotation() {
if (quat != m_xrRotation) {
m_xrRotation = quat;
if (!isRunning()) {
qCCritical(KWIN_XR) << "\t\t\tBreezy - activate";
activate();
}
Q_EMIT xrRotationChanged();
}
}

View File

@ -0,0 +1,78 @@
#pragma once
#include <effect/quickeffect.h>
#include <QAction>
#include <QKeySequence>
#include <QQuaternion>
namespace KWin
{
class BreezyDesktopEffect : public QuickSceneEffect
{
Q_OBJECT
Q_PROPERTY(int animationDuration READ animationDuration NOTIFY animationDurationChanged)
Q_PROPERTY(qreal faceDisplacement READ faceDisplacement NOTIFY faceDisplacementChanged)
Q_PROPERTY(qreal distanceFactor READ distanceFactor NOTIFY distanceFactorChanged)
Q_PROPERTY(bool mouseInvertedX READ mouseInvertedX NOTIFY mouseInvertedXChanged)
Q_PROPERTY(bool mouseInvertedY READ mouseInvertedY NOTIFY mouseInvertedYChanged)
Q_PROPERTY(BackgroundMode backgroundMode READ backgroundMode NOTIFY backgroundModeChanged)
Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundColorChanged)
Q_PROPERTY(QQuaternion xrRotation READ xrRotation NOTIFY xrRotationChanged)
public:
enum class BackgroundMode
{
Color,
Skybox,
};
Q_ENUM(BackgroundMode)
BreezyDesktopEffect();
int requestedEffectChainPosition() const override;
int animationDuration() const;
qreal faceDisplacement() const;
qreal distanceFactor() const;
bool mouseInvertedX() const;
bool mouseInvertedY() const;
BackgroundMode backgroundMode() const;
QColor backgroundColor() const;
QQuaternion xrRotation() const;
public Q_SLOTS:
void activate();
void deactivate();
void toggle();
void updateXrRotation();
Q_SIGNALS:
void faceDisplacementChanged();
void distanceFactorChanged();
void mouseInvertedXChanged();
void mouseInvertedYChanged();
void animationDurationChanged();
void skyboxChanged();
void backgroundModeChanged();
void backgroundColorChanged();
void xrRotationChanged();
protected:
QVariantMap initialProperties(Output *screen) override;
private:
void realDeactivate();
QTimer *m_shutdownTimer;
QAction *m_toggleAction = nullptr;
QList<QKeySequence> m_toggleShortcut;
QList<ElectricBorder> m_borderActivate;
QList<ElectricBorder> m_touchBorderActivate;
QQuaternion m_xrRotation;
QTimer *m_xrRotationTimer = nullptr;
};
} // namespace KWin

View File

@ -1,85 +0,0 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#pragma once
#include <effect/quickeffect.h>
#include <QAction>
#include <QKeySequence>
#include <QQuaternion>
namespace KWin
{
class CubeEffect : public QuickSceneEffect
{
Q_OBJECT
Q_PROPERTY(int animationDuration READ animationDuration NOTIFY animationDurationChanged)
Q_PROPERTY(qreal cubeFaceDisplacement READ cubeFaceDisplacement NOTIFY cubeFaceDisplacementChanged)
Q_PROPERTY(qreal distanceFactor READ distanceFactor NOTIFY distanceFactorChanged)
Q_PROPERTY(bool mouseInvertedX READ mouseInvertedX NOTIFY mouseInvertedXChanged)
Q_PROPERTY(bool mouseInvertedY READ mouseInvertedY NOTIFY mouseInvertedYChanged)
Q_PROPERTY(BackgroundMode backgroundMode READ backgroundMode NOTIFY backgroundModeChanged)
Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY backgroundColorChanged)
Q_PROPERTY(QQuaternion xrRotation READ xrRotation NOTIFY xrRotationChanged)
public:
enum class BackgroundMode {
Color,
Skybox,
};
Q_ENUM(BackgroundMode)
CubeEffect();
int requestedEffectChainPosition() const override;
void grabbedKeyboardEvent(QKeyEvent *e) override;
bool borderActivated(ElectricBorder border) override;
int animationDuration() const;
qreal cubeFaceDisplacement() const;
qreal distanceFactor() const;
bool mouseInvertedX() const;
bool mouseInvertedY() const;
BackgroundMode backgroundMode() const;
QColor backgroundColor() const;
QQuaternion xrRotation() const;
public Q_SLOTS:
void activate();
void deactivate();
void toggle();
void updateXrRotation();
Q_SIGNALS:
void cubeFaceDisplacementChanged();
void distanceFactorChanged();
void mouseInvertedXChanged();
void mouseInvertedYChanged();
void animationDurationChanged();
void skyboxChanged();
void backgroundModeChanged();
void backgroundColorChanged();
void xrRotationChanged();
protected:
QVariantMap initialProperties(Output *screen) override;
private:
void realDeactivate();
QTimer *m_shutdownTimer;
QAction *m_toggleAction = nullptr;
QList<QKeySequence> m_toggleShortcut;
QList<ElectricBorder> m_borderActivate;
QList<ElectricBorder> m_touchBorderActivate;
QQuaternion m_xrRotation;
QTimer *m_xrRotationTimer = nullptr;
};
} // namespace KWin

View File

@ -1,15 +1,9 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "cubeeffect.h"
#include "breezydesktopeffect.h"
namespace KWin
{
KWIN_EFFECT_FACTORY_SUPPORTED(CubeEffect, "metadata.json", return CubeEffect::supported();)
KWIN_EFFECT_FACTORY_SUPPORTED(BreezyDesktopEffect, "metadata.json", return BreezyDesktopEffect::supported();)
} // namespace KWin

View File

@ -1,17 +1,9 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick
import QtQuick3D
import org.kde.kwin as KWinComponents
Node {
id: cube
readonly property var supportedModels: [
"VITURE",
"nreal air",
@ -61,9 +53,8 @@ Node {
}
Repeater3D {
id: faceRepeater
model: screens.length
delegate: CubeFace {
delegate: BreezyDesktopDisplay {
screen: screens[index]
property real screenRotation: {

View File

@ -1,14 +1,8 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick
import QtQuick3D
Model {
id: face
id: display
required property QtObject screen
required property int index
@ -20,9 +14,9 @@ Model {
lighting: DefaultMaterial.NoLighting
diffuseMap: Texture {
sourceItem: DesktopView {
screen: face.screen
width: face.screen.geometry.width
height: face.screen.geometry.height
screen: display.screen
width: display.screen.geometry.width
height: display.screen.geometry.height
}
}
}

View File

@ -1,9 +1,3 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick
import QtQuick3D

View File

@ -1,9 +1,3 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick
import org.kde.kwin as KWinComponents

View File

@ -1,13 +1,7 @@
/*
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick
import QtQuick3D
import org.kde.kwin as KWinComponents
import org.kde.kwin.effect.cube
import org.kde.kwin.effect.breezy_desktop
Item {
id: root
@ -26,13 +20,6 @@ Item {
function stop() {
}
function switchToSelected() {
// const eulerRotation = cameraController.rotation.toEulerAngles();
// const desktop = cube.screenAt(eulerRotation.y);
// KWinComponents.Workspace.currentDesktop = desktop;
// effect.deactivate();
}
View3D {
id: view
anchors.fill: parent
@ -42,18 +29,18 @@ Item {
fieldOfView: 22.55
}
Cube {
id: cube
BreezyDesktop {
id: breezyDesktop
viewportFOVHorizontal: 40.09
viewportWidth: 1920
viewportHeight: 1080
}
CubeCameraController {
CameraController {
id: cameraController
anchors.fill: parent
camera: camera
radius: 0.5 * cube.viewportHeight / Math.tan(camera.fieldOfView * Math.PI / 360)
radius: 0.5 * breezyDesktop.viewportHeight / Math.tan(camera.fieldOfView * Math.PI / 360)
Behavior on rotation {
enabled: !cameraController.busy && root.animationEnabled