Commit e04e034c authored by Nicolas Fella's avatar Nicolas Fella

Port from GConf to GSettings

Summary:
CCBUG: 386665

As discussed in bug 386665 GConf is deprecated and needs to be replaced by GSettings to keep features enabled.

Question: Do we need GConf as a fallback for PA versions without module-gsettings?

Test Plan:
Checkboxes in Advanced tab are enabled again.
Changed settings are shown in dconf-editor and vice versa.
Combine output checkbox shows/hides combined sink in applet

Reviewers: drosca, davidedmundson

Reviewed By: drosca

Subscribers: pino, lbeltrame, evpokp, rikmills, broulik, asturmlechner, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D14147
parent 0b1559c4
......@@ -20,11 +20,6 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMOptionalAddSubdirectory)
include(FindPkgConfig)
pkg_check_modules(GCONF gconf-2.0)
pkg_check_modules(GOBJECT gobject-2.0)
if (GCONF_FOUND AND GOBJECT_FOUND)
set(HAVE_GCONF TRUE)
endif()
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS
Core
......@@ -45,6 +40,16 @@ find_package(PulseAudio 5.0.0 REQUIRED)
find_package(Canberra REQUIRED)
find_package(GLIB2 REQUIRED)
option(USE_GCONF "Use legacy GConf instead of GSettings")
pkg_check_modules(GOBJECT gobject-2.0 REQUIRED)
if(USE_GCONF)
pkg_check_modules(GCONF gconf-2.0 REQUIRED)
else()
find_package(GIO REQUIRED)
set(USE_GSETTINGS True)
endif()
find_package(CanberraPulse)
set_package_properties(CanberraPulse PROPERTIES
DESCRIPTION "Pulseaudio backend for libcanberra"
......
# - Try to find the GIO libraries
# Once done this will define
#
# GIO_FOUND - system has GIO
# GIO_INCLUDE_DIR - the GIO include directory
# GIO_LIBRARIES - GIO library
#
# Copyright (c) 2010 Dario Freddi <drf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if(GIO_INCLUDE_DIR AND GIO_LIBRARIES)
# Already in cache, be silent
set(GIO_FIND_QUIETLY TRUE)
endif(GIO_INCLUDE_DIR AND GIO_LIBRARIES)
if (NOT WIN32)
include(UsePkgConfig)
pkgconfig(gio-2.0 _LibGIOIncDir _LibGIOLinkDir _LibGIOLinkFlags _LibGIOCflags)
endif(NOT WIN32)
MESSAGE(STATUS "gio include dir: ${_LibGIOIncDir}")
# first try without default paths to respect PKG_CONFIG_PATH
find_path(GIO_MAIN_INCLUDE_DIR glib.h
PATH_SUFFIXES glib-2.0
PATHS ${_LibGIOIncDir}
NO_DEFAULT_PATH)
find_path(GIO_MAIN_INCLUDE_DIR glib.h
PATH_SUFFIXES glib-2.0
PATHS ${_LibGIOIncDir} )
MESSAGE(STATUS "found gio main include dir: ${GIO_MAIN_INCLUDE_DIR}")
# search the glibconfig.h include dir under the same root where the library is found
find_library(GIO_LIBRARIES
NAMES gio-2.0
PATHS ${_LibGIOLinkDir}
NO_DEFAULT_PATH)
find_library(GIO_LIBRARIES
NAMES gio-2.0
PATHS ${_LibGIOLinkDir})
get_filename_component(GIOLibDir "${GIO_LIBRARIES}" PATH)
find_path(GIO_INTERNAL_INCLUDE_DIR glibconfig.h
PATH_SUFFIXES glib-2.0/include
PATHS ${_LibGIOIncDir} "${GIOLibDir}" ${CMAKE_SYSTEM_LIBRARY_PATH}
NO_DEFAULT_PATH)
find_path(GIO_INTERNAL_INCLUDE_DIR glibconfig.h
PATH_SUFFIXES glib-2.0/include
PATHS ${_LibGIOIncDir} "${GIOLibDir}" ${CMAKE_SYSTEM_LIBRARY_PATH})
set(GIO_INCLUDE_DIR "${GIO_MAIN_INCLUDE_DIR}")
# not sure if this include dir is optional or required
# for now it is optional
if(GIO_INTERNAL_INCLUDE_DIR)
set(GIO_INCLUDE_DIR ${GIO_INCLUDE_DIR} "${GIO_INTERNAL_INCLUDE_DIR}")
endif(GIO_INTERNAL_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GIO DEFAULT_MSG GIO_LIBRARIES GIO_MAIN_INCLUDE_DIR)
mark_as_advanced(GIO_INCLUDE_DIR GIO_LIBRARIES)
/* config.h. Generated by cmake from config.h.cmake */
#cmakedefine01 HAVE_GCONF
#cmakedefine01 USE_GSETTINGS
#cmakedefine01 USE_GCONF
......@@ -37,11 +37,16 @@ set(qml_SRCS
set_property(SOURCE qml/dbus/osdService.xml APPEND PROPERTY CLASSNAME OsdServiceInterface)
qt5_add_dbus_interface(dbus_SRCS qml/dbus/osdService.xml osdservice)
if (HAVE_GCONF)
if (USE_GCONF)
include_directories(${GCONF_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS})
set(cpp_SRCS ${cpp_SRCS} gconfitem.cpp)
endif()
if (USE_GSETTINGS)
include_directories(${GIO_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS})
set(cpp_SRCS ${cpp_SRCS} gsettingsitem.cpp)
endif()
add_library(plasma-volume-declarative SHARED ${dbus_SRCS} ${cpp_SRCS} ${qml_SRCS})
target_link_libraries(plasma-volume-declarative
Qt5::Core
......@@ -52,12 +57,19 @@ target_link_libraries(plasma-volume-declarative
Canberra::Canberra
${PULSEAUDIO_LIBRARY}
${PULSEAUDIO_MAINLOOP_LIBRARY}
${GOBJECT_LIBRARIES}
)
if (HAVE_GCONF)
if (USE_GCONF)
target_link_libraries(plasma-volume-declarative
${GCONF_LDFLAGS}
${GOBJECT_LDFLAGS}
)
endif()
if (USE_GSETTINGS)
target_link_libraries(plasma-volume-declarative
${GIO_LIBRARIES}
GLIB2::GLIB2
)
endif()
......
/*
* Copyright (C) 2018 Nicolas Fella <nicolas.fella@gmx.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <QString>
#include <QVariant>
#include <gio/gio.h>
#include "gsettingsitem.h"
#include "debug.h"
QVariant GSettingsItem::value(const QString &key) const
{
GVariant *gvalue = g_settings_get_value(m_settings, key.toLatin1().data());
QVariant toReturn;
switch (g_variant_classify(gvalue)) {
case G_VARIANT_CLASS_BOOLEAN:
toReturn = QVariant((bool)g_variant_get_boolean(gvalue));
break;
case G_VARIANT_CLASS_STRING:
toReturn = QVariant(QString::fromUtf8(g_variant_get_string(gvalue, nullptr)));
break;
default:
qCWarning(PLASMAPA()) << "Unhandled variant type in value()";
}
g_variant_unref(gvalue);
return toReturn;
}
void GSettingsItem::set(const QString &key, const QVariant &val)
{
// It might be hard to detect the right GVariant type from
// complext QVariant types such as string lists or more detailed
// types such as integers (GVariant has different sizes),
// therefore we get the current value for the key and convert
// to QVariant using the GVariant type
GVariant *oldValue = g_settings_get_value(m_settings, key.toLatin1().data());
GVariant *newValue = nullptr;
switch (g_variant_type_peek_string(g_variant_get_type(oldValue))[0]) {
case G_VARIANT_CLASS_BOOLEAN:
newValue = g_variant_new_boolean(val.toBool());
break;
case G_VARIANT_CLASS_STRING:
newValue = g_variant_new_string(val.toString().toUtf8().constData());
break;
default:
qCWarning(PLASMAPA()) << "Unhandled variant type in set()";
}
if (newValue) {
g_settings_set_value(m_settings, key.toLatin1().data(), newValue);
}
g_variant_unref(oldValue);
}
GSettingsItem::GSettingsItem(const QString &key, QObject *parent)
: QObject (parent)
{
m_settings = g_settings_new_with_path("org.freedesktop.pulseaudio.module-group", key.toLatin1().data());
g_signal_connect(m_settings, "changed", G_CALLBACK(GSettingsItem::settingChanged), this);
}
GSettingsItem::~GSettingsItem()
{
g_settings_sync();
if (m_settings)
g_object_unref(m_settings);
}
/*
* Copyright (C) 2018 Nicolas Fella <nicolas.fella@gmx.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#ifndef GSETTINGSITEM_H
#define GSETTINGSITEM_H
#include <QVariant>
#include <QStringList>
#include <QObject>
#include <gio/gio.h>
class GSettingsItem : public QObject
{
Q_OBJECT
public:
explicit GSettingsItem(const QString &key, QObject *parent = nullptr);
virtual ~GSettingsItem() override;
QVariant value(const QString &key) const;
void set(const QString &key, const QVariant &val);
Q_SIGNALS:
void subtreeChanged();
private:
GSettings *m_settings;
static void settingChanged(GSettings *settings, const gchar *key, gpointer data)
{
Q_UNUSED(settings)
Q_UNUSED(key)
GSettingsItem *self = static_cast<GSettingsItem *>(data);
Q_EMIT self->subtreeChanged();
}
};
#endif // GCONFITEM_H
......@@ -79,7 +79,7 @@ ScrollView {
text: i18nd("kcm_pulseaudio", "Add virtual output device for simultaneous output on all local sound cards")
checked: moduleManager.combineSinks
onCheckedChanged: moduleManager.combineSinks = checked;
enabled: moduleManager.loadedModules.indexOf("module-gconf") != -1
enabled: moduleManager.configModuleLoaded
visible: moduleManager.settingsSupported
}
......@@ -90,7 +90,7 @@ ScrollView {
text: i18nd("kcm_pulseaudio", "Automatically switch all running streams when a new output becomes available")
checked: moduleManager.switchOnConnect
onCheckedChanged: moduleManager.switchOnConnect = checked;
enabled: moduleManager.loadedModules.indexOf("module-gconf") != -1
enabled: moduleManager.configModuleLoaded
visible: moduleManager.settingsSupported
}
......@@ -98,8 +98,8 @@ ScrollView {
Layout.alignment: Qt.AlignHCenter
enabled: false
font.italic: true
text: i18nd("kcm_pulseaudio", "Requires 'module-gconf' PulseAudio module")
visible: moduleManager.settingsSupported && moduleManager.loadedModules.indexOf("module-gconf") == -1
text: i18nd("kcm_pulseaudio", "Requires %1 PulseAudio module", moduleManager.configModuleName)
visible: moduleManager.settingsSupported && !moduleManager.configModuleLoaded
}
Header {
......
......@@ -23,10 +23,15 @@
#include "module.h"
#include "../config.h"
#if HAVE_GCONF
#if USE_GSETTINGS
#include "gsettingsitem.h"
#define PA_SETTINGS_PATH_MODULES "/org/freedesktop/pulseaudio/module-groups"
#endif
#if USE_GCONF
#include "gconfitem.h"
#define PA_GCONF_ROOT "/system/pulseaudio"
#define PA_GCONF_PATH_MODULES PA_GCONF_ROOT"/modules"
#define PA_SETTINGS_PATH_MODULES "/system/pulseaudio/modules"
#endif
#include <QTimer>
......@@ -34,29 +39,38 @@
namespace QPulseAudio
{
#if HAVE_GCONF
class GConfModule : public GConfItem
#if USE_GCONF || USE_GSETTINGS
#if USE_GSETTINGS
class ConfigModule : public GSettingsItem
#elif USE_GCONF
class ConfigModule : public GConfItem
#endif
{
public:
GConfModule(const QString &configName, const QString &moduleName, QObject *parent);
ConfigModule(const QString &configName, const QString &moduleName, QObject *parent);
bool isEnabled() const;
void setEnabled(bool enabled, const QVariant &args=QVariant());
private:
QString m_moduleName;
};
GConfModule::GConfModule(const QString &configName, const QString &moduleName, QObject *parent) :
GConfItem(QStringLiteral(PA_GCONF_PATH_MODULES"/") + configName, parent),
ConfigModule::ConfigModule(const QString &configName, const QString &moduleName, QObject *parent) :
#if USE_GSETTINGS
GSettingsItem(QStringLiteral(PA_SETTINGS_PATH_MODULES"/") + configName + QStringLiteral("/"), parent),
#elif USE_GCONF
GConfItem(QStringLiteral(PA_SETTINGS_PATH_MODULES"/") + configName, parent),
#endif
m_moduleName(moduleName)
{
}
bool GConfModule::isEnabled() const
bool ConfigModule::isEnabled() const
{
return value(QStringLiteral("enabled")).toBool();
}
void GConfModule::setEnabled(bool enabled, const QVariant &args)
void ConfigModule::setEnabled(bool enabled, const QVariant &args)
{
set(QStringLiteral("locked"), true);
......@@ -69,20 +83,20 @@ void GConfModule::setEnabled(bool enabled, const QVariant &args)
}
set(QStringLiteral("locked"), false);
}
#endif
#endif
ModuleManager::ModuleManager(QObject *parent) :
QObject(parent)
{
#if HAVE_GCONF
m_combineSinks = new GConfModule(QStringLiteral("combine"), QStringLiteral("module-combine"), this);
m_switchOnConnect = new GConfModule(QStringLiteral("switch-on-connect"), QStringLiteral("module-switch-on-connect"), this);
m_deviceManager = new GConfModule(QStringLiteral("device-manager"), QStringLiteral("module-device-manager"), this);
connect(m_combineSinks, &GConfItem::subtreeChanged, this, &ModuleManager::combineSinksChanged);
connect(m_switchOnConnect, &GConfItem::subtreeChanged, this, &ModuleManager::switchOnConnectChanged);
connect(m_deviceManager, &GConfItem::subtreeChanged, this, &ModuleManager::switchOnConnectChanged);
#if USE_GCONF || USE_GSETTINGS
m_combineSinks = new ConfigModule(QStringLiteral("combine"), QStringLiteral("module-combine"), this);
m_switchOnConnect = new ConfigModule(QStringLiteral("switch-on-connect"), QStringLiteral("module-switch-on-connect"), this);
m_deviceManager = new ConfigModule(QStringLiteral("device-manager"), QStringLiteral("module-device-manager"), this);
connect(m_combineSinks, &ConfigModule::subtreeChanged, this, &ModuleManager::combineSinksChanged);
connect(m_switchOnConnect, &ConfigModule::subtreeChanged, this, &ModuleManager::switchOnConnectChanged);
connect(m_deviceManager, &ConfigModule::subtreeChanged, this, &ModuleManager::switchOnConnectChanged);
#endif
QTimer *updateModulesTimer = new QTimer(this);
......@@ -100,7 +114,7 @@ ModuleManager::~ModuleManager()
bool ModuleManager::settingsSupported() const
{
#if HAVE_GCONF
#if USE_GCONF || USE_GSETTINGS
return true;
#else
return false;
......@@ -109,7 +123,7 @@ bool ModuleManager::settingsSupported() const
bool ModuleManager::combineSinks() const
{
#if HAVE_GCONF
#if USE_GCONF || USE_GSETTINGS
return m_combineSinks->isEnabled();
#else
return false;
......@@ -118,21 +132,21 @@ bool ModuleManager::combineSinks() const
void ModuleManager::setCombineSinks(bool combineSinks)
{
#if HAVE_GCONF
#if USE_GCONF || USE_GSETTINGS
m_combineSinks->setEnabled(combineSinks);
#else
Q_UNUSED(combineSinks)
Q_UNUSED(combineSinks()
#endif
}
bool ModuleManager::switchOnConnect() const
{
#if USE_GCONF || USE_GSETTINGS
//switch on connect and device-manager do the same task. Only one should be enabled
//Note on the first run m_deviceManager will appear to be disabled even though it's actually running
//because there is no gconf entry, however m_switchOnConnect will only exist if set by Plasma PA
//hence only check this entry
#if HAVE_GCONF
return m_switchOnConnect->isEnabled() ;
#else
return false;
......@@ -141,7 +155,7 @@ bool ModuleManager::switchOnConnect() const
void ModuleManager::setSwitchOnConnect(bool switchOnConnect)
{
#if HAVE_GCONF
#if USE_GCONF || USE_GSETTINGS
m_deviceManager->setEnabled(!switchOnConnect);
m_switchOnConnect->setEnabled(switchOnConnect);
#else
......@@ -164,4 +178,19 @@ void ModuleManager::updateLoadedModules()
Q_EMIT loadedModulesChanged();
}
bool ModuleManager::configModuleLoaded() const
{
return m_loadedModules.contains(configModuleName());
}
QString ModuleManager::configModuleName() const
{
#if USE_GCONF
return QStringLiteral("module-gconf");
#elif USE_GSETTINGS
return QStringLiteral("module-gsettings");
#else
return QString();
#endif
}
}
......@@ -29,11 +29,9 @@
// Properties need fully qualified classes even with pointers.
#include "client.h"
class GConfItem;
namespace QPulseAudio
{
class GConfModule;
class ConfigModule;
class ModuleManager : public QObject
{
......@@ -41,6 +39,8 @@ class ModuleManager : public QObject
Q_PROPERTY(bool settingsSupported READ settingsSupported CONSTANT)
Q_PROPERTY(bool combineSinks READ combineSinks WRITE setCombineSinks NOTIFY combineSinksChanged)
Q_PROPERTY(bool switchOnConnect READ switchOnConnect WRITE setSwitchOnConnect NOTIFY switchOnConnectChanged)
Q_PROPERTY(bool configModuleLoaded READ configModuleLoaded NOTIFY loadedModulesChanged)
Q_PROPERTY(QString configModuleName READ configModuleName CONSTANT)
Q_PROPERTY(QStringList loadedModules READ loadedModules NOTIFY loadedModulesChanged)
public:
explicit ModuleManager(QObject *parent = nullptr);
......@@ -52,6 +52,8 @@ public:
bool switchOnConnect() const;
void setSwitchOnConnect(bool switchOnConnect);
QStringList loadedModules() const;
bool configModuleLoaded() const;
QString configModuleName() const;
Q_SIGNALS:
void combineSinksChanged();
......@@ -61,9 +63,9 @@ Q_SIGNALS:
private:
void updateLoadedModules();
GConfModule *m_combineSinks;
GConfModule *m_switchOnConnect;
GConfModule *m_deviceManager;
ConfigModule *m_combineSinks;
ConfigModule *m_switchOnConnect;
ConfigModule *m_deviceManager;
QStringList m_loadedModules;
};
......
Markdown is supported
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