[kcmkwin/desktop] Add animation option back
Summary: The "new" animation option no longer uses hard coded effects, which means one could install a third party virtual desktop switching animation, for example from store.kde.org, and it will be displayed in the KCM. Test Plan: {F6503565} Reviewers: #kwin, #vdg, ngraham, davidedmundson Reviewed By: #kwin, #vdg, ngraham, davidedmundson Subscribers: davidedmundson, hein, ngraham, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D17766
This commit is contained in:
parent
c3fd6413b9
commit
aaaca19b0e
6 changed files with 415 additions and 1 deletions
|
@ -6,7 +6,12 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwin_virtualdesktops\")
|
|||
|
||||
########### next target ###############
|
||||
|
||||
set(kcm_kwin_virtualdesktops_PART_SRCS virtualdesktops.cpp desktopsmodel.cpp ../../virtualdesktopsdbustypes.cpp)
|
||||
set(kcm_kwin_virtualdesktops_PART_SRCS
|
||||
virtualdesktops.cpp
|
||||
animationsmodel.cpp
|
||||
desktopsmodel.cpp
|
||||
../../virtualdesktopsdbustypes.cpp
|
||||
)
|
||||
|
||||
add_library(kcm_kwin_virtualdesktops MODULE ${kcm_kwin_virtualdesktops_PART_SRCS})
|
||||
|
||||
|
@ -15,6 +20,8 @@ target_link_libraries(kcm_kwin_virtualdesktops
|
|||
KF5::I18n
|
||||
KF5::KCMUtils
|
||||
KF5::QuickAddons
|
||||
KF5::XmlGui
|
||||
kcmkwincommon
|
||||
)
|
||||
|
||||
kcoreaddons_desktop_to_json(kcm_kwin_virtualdesktops "kcm_kwin_virtualdesktops.desktop")
|
||||
|
|
154
kcmkwin/kwindesktop/animationsmodel.cpp
Normal file
154
kcmkwin/kwindesktop/animationsmodel.cpp
Normal file
|
@ -0,0 +1,154 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "animationsmodel.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
AnimationsModel::AnimationsModel(QObject *parent)
|
||||
: EffectModel(parent)
|
||||
{
|
||||
connect(this, &AnimationsModel::currentIndexChanged, this,
|
||||
[this] {
|
||||
const QModelIndex index_ = index(m_currentIndex, 0);
|
||||
if (!index_.isValid()) {
|
||||
return;
|
||||
}
|
||||
const bool configurable = index_.data(ConfigurableRole).toBool();
|
||||
if (configurable != m_currentConfigurable) {
|
||||
m_currentConfigurable = configurable;
|
||||
emit currentConfigurableChanged();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
bool AnimationsModel::enabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void AnimationsModel::setEnabled(bool enabled)
|
||||
{
|
||||
if (m_enabled != enabled) {
|
||||
m_enabled = enabled;
|
||||
emit enabledChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int AnimationsModel::currentIndex() const
|
||||
{
|
||||
return m_currentIndex;
|
||||
}
|
||||
|
||||
void AnimationsModel::setCurrentIndex(int index)
|
||||
{
|
||||
if (m_currentIndex != index) {
|
||||
m_currentIndex = index;
|
||||
emit currentIndexChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool AnimationsModel::currentConfigurable() const
|
||||
{
|
||||
return m_currentConfigurable;
|
||||
}
|
||||
|
||||
bool AnimationsModel::shouldStore(const EffectData &data) const
|
||||
{
|
||||
return data.untranslatedCategory.contains(
|
||||
QStringLiteral("Virtual Desktop Switching Animation"), Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
EffectModel::Status AnimationsModel::status(int row) const
|
||||
{
|
||||
return Status(data(index(row, 0), static_cast<int>(EffectStatusRole)).toInt());
|
||||
}
|
||||
|
||||
bool AnimationsModel::modelCurrentEnabled() const
|
||||
{
|
||||
for (int i = 0; i < rowCount(); ++i) {
|
||||
if (status(i) != Status::Disabled) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int AnimationsModel::modelCurrentIndex() const
|
||||
{
|
||||
for (int i = 0; i < rowCount(); ++i) {
|
||||
if (status(i) != Status::Disabled) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AnimationsModel::load()
|
||||
{
|
||||
EffectModel::load();
|
||||
setEnabled(modelCurrentEnabled());
|
||||
setCurrentIndex(modelCurrentIndex());
|
||||
}
|
||||
|
||||
void AnimationsModel::save()
|
||||
{
|
||||
for (int i = 0; i < rowCount(); ++i) {
|
||||
const auto status = (m_enabled && i == m_currentIndex)
|
||||
? EffectModel::Status::Enabled
|
||||
: EffectModel::Status::Disabled;
|
||||
updateEffectStatus(index(i, 0), status);
|
||||
}
|
||||
|
||||
EffectModel::save();
|
||||
}
|
||||
|
||||
void AnimationsModel::defaults()
|
||||
{
|
||||
EffectModel::defaults();
|
||||
setEnabled(modelCurrentEnabled());
|
||||
setCurrentIndex(modelCurrentIndex());
|
||||
}
|
||||
|
||||
bool AnimationsModel::needsSave() const
|
||||
{
|
||||
KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins");
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i) {
|
||||
const QModelIndex index_ = index(i, 0);
|
||||
const bool enabledConfig = kwinConfig.readEntry(
|
||||
index_.data(ServiceNameRole).toString() + QLatin1String("Enabled"),
|
||||
index_.data(EnabledByDefaultRole).toBool()
|
||||
);
|
||||
const bool enabled = (m_enabled && i == m_currentIndex);
|
||||
|
||||
if (enabled != enabledConfig) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
71
kcmkwin/kwindesktop/animationsmodel.h
Normal file
71
kcmkwin/kwindesktop/animationsmodel.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "effectmodel.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class AnimationsModel : public EffectModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
||||
Q_PROPERTY(bool currentConfigurable READ currentConfigurable NOTIFY currentConfigurableChanged)
|
||||
|
||||
public:
|
||||
explicit AnimationsModel(QObject *parent = nullptr);
|
||||
|
||||
bool enabled() const;
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
int currentIndex() const;
|
||||
void setCurrentIndex(int index);
|
||||
|
||||
bool currentConfigurable() const;
|
||||
|
||||
void load();
|
||||
void save();
|
||||
void defaults();
|
||||
bool needsSave() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void enabledChanged();
|
||||
void currentIndexChanged();
|
||||
void currentConfigurableChanged();
|
||||
|
||||
protected:
|
||||
bool shouldStore(const EffectData &data) const override;
|
||||
|
||||
private:
|
||||
Status status(int row) const;
|
||||
bool modelCurrentEnabled() const;
|
||||
int modelCurrentIndex() const;
|
||||
|
||||
bool m_enabled = false;
|
||||
int m_currentIndex = -1;
|
||||
bool m_currentConfigurable = false;
|
||||
|
||||
Q_DISABLE_COPY(AnimationsModel)
|
||||
};
|
||||
|
||||
}
|
|
@ -200,6 +200,49 @@ ScrollViewKCM {
|
|||
onCheckedChanged: kcm.navWraps = checked
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
QtControls.CheckBox {
|
||||
id: animationEnabled
|
||||
|
||||
text: i18n("Show animation when switching:")
|
||||
|
||||
checked: kcm.animationsModel.enabled
|
||||
|
||||
onCheckedChanged: kcm.animationsModel.enabled = checked
|
||||
}
|
||||
|
||||
QtControls.ComboBox {
|
||||
enabled: animationEnabled.checked
|
||||
|
||||
model: kcm.animationsModel
|
||||
textRole: "NameRole"
|
||||
currentIndex: kcm.animationsModel.currentIndex
|
||||
onActivated: kcm.animationsModel.currentIndex = currentIndex
|
||||
}
|
||||
|
||||
QtControls.Button {
|
||||
enabled: animationEnabled.checked && kcm.animationsModel.currentConfigurable
|
||||
|
||||
icon.name: "configure"
|
||||
|
||||
onClicked: kcm.configureAnimation()
|
||||
}
|
||||
|
||||
QtControls.Button {
|
||||
enabled: animationEnabled.checked
|
||||
|
||||
icon.name: "dialog-information"
|
||||
|
||||
onClicked: kcm.showAboutAnimation()
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Eike Hein <hein@kde.org>
|
||||
* Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -16,12 +17,21 @@
|
|||
*/
|
||||
|
||||
#include "virtualdesktops.h"
|
||||
#include "animationsmodel.h"
|
||||
#include "desktopsmodel.h"
|
||||
|
||||
#include <KAboutApplicationDialog>
|
||||
#include <KAboutData>
|
||||
#include <KCModule>
|
||||
#include <KConfigGroup>
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginFactory>
|
||||
#include <KPluginTrader>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON(VirtualDesktopsFactory, "kcm_kwin_virtualdesktops.json", registerPlugin<KWin::VirtualDesktops>();)
|
||||
|
||||
|
@ -36,6 +46,7 @@ VirtualDesktops::VirtualDesktops(QObject *parent, const QVariantList &args)
|
|||
, m_osdEnabled(false)
|
||||
, m_osdDuration(1000)
|
||||
, m_osdTextOnly(false)
|
||||
, m_animationsModel(new AnimationsModel(this))
|
||||
{
|
||||
KAboutData *about = new KAboutData(QStringLiteral("kcm_kwin_virtualdesktops"),
|
||||
i18n("Configure Virtual Desktops"),
|
||||
|
@ -46,6 +57,10 @@ VirtualDesktops::VirtualDesktops(QObject *parent, const QVariantList &args)
|
|||
|
||||
QObject::connect(m_desktopsModel, &KWin::DesktopsModel::userModifiedChanged,
|
||||
this, &VirtualDesktops::updateNeedsSave);
|
||||
connect(m_animationsModel, &AnimationsModel::enabledChanged,
|
||||
this, &VirtualDesktops::updateNeedsSave);
|
||||
connect(m_animationsModel, &AnimationsModel::currentIndexChanged,
|
||||
this, &VirtualDesktops::updateNeedsSave);
|
||||
}
|
||||
|
||||
VirtualDesktops::~VirtualDesktops()
|
||||
|
@ -121,6 +136,11 @@ void VirtualDesktops::setOsdTextOnly(bool textOnly)
|
|||
}
|
||||
}
|
||||
|
||||
QAbstractItemModel *VirtualDesktops::animationsModel() const
|
||||
{
|
||||
return m_animationsModel;
|
||||
}
|
||||
|
||||
void VirtualDesktops::load()
|
||||
{
|
||||
KConfigGroup navConfig(m_kwinConfig, "Windows");
|
||||
|
@ -132,11 +152,14 @@ void VirtualDesktops::load()
|
|||
KConfigGroup osdSettings(m_kwinConfig, "Script-desktopchangeosd");
|
||||
setOsdDuration(osdSettings.readEntry("PopupHideDelay", 1000));
|
||||
setOsdTextOnly(osdSettings.readEntry("TextOnly", false));
|
||||
|
||||
m_animationsModel->load();
|
||||
}
|
||||
|
||||
void VirtualDesktops::save()
|
||||
{
|
||||
m_desktopsModel->syncWithServer();
|
||||
m_animationsModel->save();
|
||||
|
||||
KConfigGroup navConfig(m_kwinConfig, "Windows");
|
||||
navConfig.writeEntry("RollOverDesktops", m_navWraps);
|
||||
|
@ -160,6 +183,7 @@ void VirtualDesktops::save()
|
|||
void VirtualDesktops::defaults()
|
||||
{
|
||||
m_desktopsModel->setRows(1);
|
||||
m_animationsModel->defaults();
|
||||
|
||||
setNavWraps(true);
|
||||
setOsdEnabled(false);
|
||||
|
@ -167,6 +191,108 @@ void VirtualDesktops::defaults()
|
|||
setOsdTextOnly(false);
|
||||
}
|
||||
|
||||
void VirtualDesktops::configureAnimation()
|
||||
{
|
||||
const QModelIndex index = m_animationsModel->index(m_animationsModel->currentIndex(), 0);
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString name = index.data(AnimationsModel::NameRole).toString();
|
||||
const QString serviceName = index.data(AnimationsModel::ServiceNameRole).toString();
|
||||
|
||||
QPointer<QDialog> configDialog = new QDialog();
|
||||
|
||||
KCModule *kcm = KPluginTrader::createInstanceFromQuery<KCModule>(
|
||||
QStringLiteral("kwin/effects/configs/"),
|
||||
QString(),
|
||||
QStringLiteral("'%1' in [X-KDE-ParentComponents]").arg(serviceName),
|
||||
configDialog
|
||||
);
|
||||
|
||||
if (!kcm) {
|
||||
delete configDialog;
|
||||
return;
|
||||
}
|
||||
|
||||
configDialog->setWindowTitle(name);
|
||||
configDialog->setLayout(new QVBoxLayout);
|
||||
|
||||
auto buttons = new QDialogButtonBox(
|
||||
QDialogButtonBox::Ok |
|
||||
QDialogButtonBox::Cancel |
|
||||
QDialogButtonBox::RestoreDefaults,
|
||||
configDialog
|
||||
);
|
||||
QObject::connect(buttons, &QDialogButtonBox::accepted, configDialog, &QDialog::accept);
|
||||
QObject::connect(buttons, &QDialogButtonBox::rejected, configDialog, &QDialog::reject);
|
||||
QObject::connect(buttons->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, kcm, &KCModule::defaults);
|
||||
|
||||
auto showWidget = new QWidget(configDialog);
|
||||
auto layout = new QVBoxLayout;
|
||||
showWidget->setLayout(layout);
|
||||
layout->addWidget(kcm);
|
||||
configDialog->layout()->addWidget(showWidget);
|
||||
configDialog->layout()->addWidget(buttons);
|
||||
|
||||
if (configDialog->exec() == QDialog::Accepted) {
|
||||
kcm->save();
|
||||
} else if (!configDialog.isNull()) {
|
||||
kcm->load();
|
||||
}
|
||||
|
||||
delete configDialog;
|
||||
}
|
||||
|
||||
void VirtualDesktops::showAboutAnimation()
|
||||
{
|
||||
const QModelIndex index = m_animationsModel->index(m_animationsModel->currentIndex(), 0);
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString name = index.data(AnimationsModel::NameRole).toString();
|
||||
const QString comment = index.data(AnimationsModel::DescriptionRole).toString();
|
||||
const QString author = index.data(AnimationsModel::AuthorNameRole).toString();
|
||||
const QString email = index.data(AnimationsModel::AuthorEmailRole).toString();
|
||||
const QString website = index.data(AnimationsModel::WebsiteRole).toString();
|
||||
const QString version = index.data(AnimationsModel::VersionRole).toString();
|
||||
const QString license = index.data(AnimationsModel::LicenseRole).toString();
|
||||
const QString icon = index.data(AnimationsModel::IconNameRole).toString();
|
||||
|
||||
const KAboutLicense::LicenseKey licenseType = KAboutLicense::byKeyword(license).key();
|
||||
|
||||
KAboutData aboutData(
|
||||
name, // Plugin name
|
||||
name, // Display name
|
||||
version, // Version
|
||||
comment, // Short description
|
||||
licenseType, // License
|
||||
QString(), // Copyright statement
|
||||
QString(), // Other text
|
||||
website.toLatin1() // Home page
|
||||
);
|
||||
aboutData.setProgramLogo(icon);
|
||||
|
||||
const QStringList authors = author.split(',');
|
||||
const QStringList emails = email.split(',');
|
||||
|
||||
if (authors.count() == emails.count()) {
|
||||
int i = 0;
|
||||
for (const QString &author : authors) {
|
||||
if (!author.isEmpty()) {
|
||||
aboutData.addAuthor(i18n(author.toUtf8()), QString(), emails[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
QPointer<KAboutApplicationDialog> aboutPlugin = new KAboutApplicationDialog(aboutData);
|
||||
aboutPlugin->exec();
|
||||
|
||||
delete aboutPlugin;
|
||||
}
|
||||
|
||||
void VirtualDesktops::updateNeedsSave()
|
||||
{
|
||||
bool needsSave = false;
|
||||
|
@ -175,6 +301,10 @@ void VirtualDesktops::updateNeedsSave()
|
|||
needsSave = true;
|
||||
}
|
||||
|
||||
if (m_animationsModel->needsSave()) {
|
||||
needsSave = true;
|
||||
}
|
||||
|
||||
KConfigGroup navConfig(m_kwinConfig, "Windows");
|
||||
|
||||
if (m_navWraps != navConfig.readEntry<bool>("RollOverDesktops", true)) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2018 Eike Hein <hein@kde.org>
|
||||
* Copyright (C) 2018 Vlad Zagorodniy <vladzzag@gmail.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -24,6 +25,7 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class AnimationsModel;
|
||||
class DesktopsModel;
|
||||
|
||||
class VirtualDesktops : public KQuickAddons::ConfigModule
|
||||
|
@ -35,6 +37,7 @@ class VirtualDesktops : public KQuickAddons::ConfigModule
|
|||
Q_PROPERTY(bool osdEnabled READ osdEnabled WRITE setOsdEnabled NOTIFY osdEnabledChanged)
|
||||
Q_PROPERTY(int osdDuration READ osdDuration WRITE setOsdDuration NOTIFY osdDurationChanged)
|
||||
Q_PROPERTY(bool osdTextOnly READ osdTextOnly WRITE setOsdTextOnly NOTIFY osdTextOnlyChanged)
|
||||
Q_PROPERTY(QAbstractItemModel *animationsModel READ animationsModel CONSTANT)
|
||||
|
||||
public:
|
||||
explicit VirtualDesktops(QObject *parent = nullptr, const QVariantList &list = QVariantList());
|
||||
|
@ -54,6 +57,8 @@ public:
|
|||
int osdTextOnly() const;
|
||||
void setOsdTextOnly(bool textOnly);
|
||||
|
||||
QAbstractItemModel *animationsModel() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void navWrapsChanged() const;
|
||||
void osdEnabledChanged() const;
|
||||
|
@ -65,6 +70,9 @@ public Q_SLOTS:
|
|||
void save() override;
|
||||
void defaults() override;
|
||||
|
||||
void configureAnimation();
|
||||
void showAboutAnimation();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateNeedsSave();
|
||||
|
||||
|
@ -75,6 +83,7 @@ private:
|
|||
bool m_osdEnabled;
|
||||
int m_osdDuration;
|
||||
bool m_osdTextOnly;
|
||||
AnimationsModel *m_animationsModel;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue