92edeb1fe4
svn path=/trunk/KDE/kdebase/workspace/; revision=999968
495 lines
18 KiB
C++
495 lines
18 KiB
C++
/********************************************************************
|
|
KWin - the KDE window manager
|
|
This file is part of the KDE project.
|
|
|
|
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.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 "main.h"
|
|
|
|
#include <QDBusMessage>
|
|
#include <QDBusConnection>
|
|
|
|
#include <KAboutApplicationDialog>
|
|
#include <KActionCollection>
|
|
#include <KAction>
|
|
#include <KCModuleProxy>
|
|
#include <KPluginInfo>
|
|
#include <KPluginFactory>
|
|
#include <KConfigGroup>
|
|
#include <KService>
|
|
#include <KServiceTypeTrader>
|
|
#include <KShortcutsEditor>
|
|
|
|
#ifdef Q_WS_X11
|
|
#include <QX11Info>
|
|
#endif
|
|
|
|
#include <netwm.h>
|
|
|
|
K_PLUGIN_FACTORY( KWinDesktopConfigFactory, registerPlugin<KWin::KWinDesktopConfig>(); )
|
|
K_EXPORT_PLUGIN( KWinDesktopConfigFactory( "kcm_kwindesktop" ))
|
|
|
|
namespace KWin
|
|
{
|
|
|
|
KWinDesktopConfigForm::KWinDesktopConfigForm( QWidget* parent )
|
|
: QWidget( parent )
|
|
{
|
|
setupUi( this );
|
|
}
|
|
|
|
KWinDesktopConfig::KWinDesktopConfig( QWidget* parent, const QVariantList& args )
|
|
: KCModule( KWinDesktopConfigFactory::componentData(), parent, args )
|
|
, m_config( KSharedConfig::openConfig( "kwinrc" ))
|
|
{
|
|
init();
|
|
}
|
|
|
|
void KWinDesktopConfig::init()
|
|
{
|
|
m_ui = new KWinDesktopConfigForm( this );
|
|
// TODO: there has to be a way to add the shortcuts editor to the ui file
|
|
m_editor = new KShortcutsEditor( m_ui, KShortcutsEditor::GlobalAction );
|
|
m_ui->editorFrame->setLayout( new QVBoxLayout() );
|
|
m_ui->editorFrame->layout()->setMargin( 0 );
|
|
m_ui->editorFrame->layout()->addWidget( m_editor );
|
|
|
|
m_ui->desktopNames->setDesktopConfig( this );
|
|
m_ui->desktopNames->setMaxDesktops( maxDesktops );
|
|
m_ui->desktopNames->numberChanged( defaultDesktops );
|
|
|
|
QVBoxLayout* layout = new QVBoxLayout( this );
|
|
layout->addWidget( m_ui );
|
|
|
|
setQuickHelp( i18n("<h1>Multiple Desktops</h1>In this module, you can configure how many virtual desktops you want and how these should be labeled."));
|
|
|
|
// Shortcut config. The shortcut belongs to the component "kwin"!
|
|
m_actionCollection = new KActionCollection( this, KComponentData("kwin") );
|
|
m_actionCollection->setConfigGroup( "Desktop Switching" );
|
|
m_actionCollection->setConfigGlobal( true );
|
|
|
|
m_switchDesktopCollection = new KActionCollection( this, KComponentData("kwin") );
|
|
m_switchDesktopCollection->setConfigGroup( "Desktop Switching" );
|
|
m_switchDesktopCollection->setConfigGlobal( true );
|
|
|
|
// actions for switch desktop collection - other action is filled dynamically
|
|
KAction* a = qobject_cast<KAction*>(m_switchDesktopCollection->addAction( "Switch to Next Desktop" ));
|
|
a->setText( i18n( "Switch to Next Desktop" ));
|
|
a->setGlobalShortcut( KShortcut(), KAction::ActiveShortcut );
|
|
a = qobject_cast<KAction*>(m_switchDesktopCollection->addAction( "Switch to Previous Desktop" ));
|
|
a->setText( i18n( "Switch to Previous Desktop" ));
|
|
a->setGlobalShortcut( KShortcut(), KAction::ActiveShortcut );
|
|
a = qobject_cast<KAction*>(m_switchDesktopCollection->addAction( "Switch One Desktop to the Right" ));
|
|
a->setText( i18n( "Switch One Desktop to the Right" ));
|
|
a->setGlobalShortcut( KShortcut(), KAction::ActiveShortcut );
|
|
a = qobject_cast<KAction*>(m_switchDesktopCollection->addAction( "Switch One Desktop to the Left" ));
|
|
a->setText( i18n( "Switch One Desktop to the Left" ));
|
|
a->setGlobalShortcut( KShortcut(), KAction::ActiveShortcut );
|
|
a = qobject_cast<KAction*>(m_switchDesktopCollection->addAction( "Switch One Desktop Up" ));
|
|
a->setText( i18n( "Switch One Desktop Up" ));
|
|
a->setGlobalShortcut( KShortcut(), KAction::ActiveShortcut );
|
|
a = qobject_cast<KAction*>(m_switchDesktopCollection->addAction( "Switch One Desktop Down" ));
|
|
a->setText( i18n( "Switch One Desktop Down" ));
|
|
a->setGlobalShortcut( KShortcut(), KAction::ActiveShortcut );
|
|
|
|
m_editor->addCollection( m_switchDesktopCollection, i18n( "Desktop Switching" ) );
|
|
m_editor->addCollection( m_actionCollection, i18n( "Desktop Switching" ) );
|
|
|
|
// search the effect names
|
|
// TODO: way to recognize if a effect is not found
|
|
KServiceTypeTrader* trader = KServiceTypeTrader::self();
|
|
KService::List services;
|
|
QString slide;
|
|
QString cube;
|
|
QString fadedesktop;
|
|
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_slide'");
|
|
if( !services.isEmpty() )
|
|
slide = services.first()->name();
|
|
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_cubeslide'");
|
|
if( !services.isEmpty() )
|
|
cube = services.first()->name();
|
|
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_fadedesktop'");
|
|
if( !services.isEmpty() )
|
|
fadedesktop = services.first()->name();
|
|
|
|
m_ui->effectComboBox->addItem(i18n("No Animation"));
|
|
m_ui->effectComboBox->addItem(slide);
|
|
m_ui->effectComboBox->addItem(cube);
|
|
m_ui->effectComboBox->addItem(fadedesktop);
|
|
|
|
// effect config and info button
|
|
m_ui->effectInfoButton->setIcon( KIcon( "dialog-information" ));
|
|
m_ui->effectConfigButton->setIcon( KIcon( "configure" ));
|
|
|
|
connect( m_ui->rowsSpinBox, SIGNAL(valueChanged(int)), SLOT(changed()));
|
|
connect( m_ui->numberSpinBox, SIGNAL(valueChanged(int)), SLOT(changed()));
|
|
connect( m_ui->numberSpinBox, SIGNAL(valueChanged(int)), SLOT(slotChangeShortcuts(int)));
|
|
connect( m_ui->activityCheckBox, SIGNAL(stateChanged(int)), SLOT(changed()));
|
|
connect( m_ui->desktopNames, SIGNAL(changed()), SLOT(changed()));
|
|
connect( m_ui->popupInfoCheckBox, SIGNAL(stateChanged(int)), SLOT(changed()));
|
|
connect( m_ui->popupHideSpinBox, SIGNAL(valueChanged(int)), SLOT(changed()));
|
|
connect( m_editor, SIGNAL(keyChange()), SLOT(changed()));
|
|
connect( m_ui->allShortcutsCheckBox, SIGNAL(stateChanged(int)), SLOT(slotShowAllShortcuts()));
|
|
connect( m_ui->effectComboBox, SIGNAL(currentIndexChanged(int)), SLOT(changed()));
|
|
connect( m_ui->effectComboBox, SIGNAL(currentIndexChanged(int)), SLOT(slotEffectSelectionChanged(int)));
|
|
connect( m_ui->effectInfoButton, SIGNAL(clicked()), SLOT(slotAboutEffectClicked()));
|
|
connect( m_ui->effectConfigButton, SIGNAL(clicked()), SLOT(slotConfigureEffectClicked()));
|
|
|
|
|
|
// Begin check for immutable - taken from old desktops kcm
|
|
#ifdef Q_WS_X11
|
|
int kwin_screen_number = DefaultScreen(QX11Info::display());
|
|
#else
|
|
int kwin_screen_number = 0;
|
|
#endif
|
|
|
|
m_config = KSharedConfig::openConfig( "kwinrc" );
|
|
|
|
QByteArray groupname;
|
|
if( kwin_screen_number == 0 )
|
|
groupname = "Desktops";
|
|
else
|
|
groupname = "Desktops-screen-" + QByteArray::number ( kwin_screen_number );
|
|
|
|
if( m_config->isGroupImmutable( groupname ) )
|
|
{
|
|
m_ui->nameGroup->setEnabled(false);
|
|
//number of desktops widgets
|
|
m_ui->numberLabel->setEnabled(false);
|
|
m_ui->numberSpinBox->setEnabled(false);
|
|
}
|
|
else
|
|
{
|
|
KConfigGroup cfgGroup(m_config.data(), groupname.constData());
|
|
if( cfgGroup.isEntryImmutable( "Number" ) )
|
|
{
|
|
//number of desktops widgets
|
|
m_ui->numberLabel->setEnabled(false);
|
|
m_ui->numberSpinBox->setEnabled(false);
|
|
}
|
|
}
|
|
// End check for immutable
|
|
}
|
|
|
|
KWinDesktopConfig::~KWinDesktopConfig()
|
|
{
|
|
}
|
|
|
|
void KWinDesktopConfig::defaults()
|
|
{
|
|
// TODO: plasma stuff
|
|
m_ui->numberSpinBox->setValue( defaultDesktops );
|
|
m_ui->desktopNames->numberChanged( defaultDesktops );
|
|
for( int i=1; i<=maxDesktops; i++ )
|
|
{
|
|
m_desktopNames[i-1] = i18n( "Desktop %1", i );
|
|
if( i <= defaultDesktops )
|
|
m_ui->desktopNames->setDefaultName( i );
|
|
}
|
|
|
|
// popup info
|
|
m_ui->popupInfoCheckBox->setChecked( false );
|
|
m_ui->popupHideSpinBox->setValue( 1000 );
|
|
|
|
m_ui->effectComboBox->setCurrentIndex( 1 );
|
|
|
|
m_editor->allDefault();
|
|
|
|
emit changed(true);
|
|
}
|
|
|
|
void KWinDesktopConfig::load()
|
|
{
|
|
#ifdef Q_WS_X11
|
|
// get number of desktops
|
|
NETRootInfo info( QX11Info::display(), NET::NumberOfDesktops | NET::DesktopNames );
|
|
int n = info.numberOfDesktops();
|
|
|
|
m_ui->numberSpinBox->setValue(n);
|
|
slotChangeShortcuts(n);
|
|
|
|
for( int i = 1; i <= maxDesktops; i++ )
|
|
{
|
|
QString name = QString::fromUtf8( info.desktopName(i) );
|
|
m_desktopNames << name;
|
|
m_ui->desktopNames->setName( i, name );
|
|
}
|
|
#endif
|
|
// Popup info
|
|
KConfigGroup popupInfo( m_config, "PopupInfo" );
|
|
m_ui->popupInfoCheckBox->setChecked( popupInfo.readEntry( "ShowPopup", false ));
|
|
m_ui->popupHideSpinBox->setValue( popupInfo.readEntry( "PopupHideDelay", 1000 ));
|
|
m_ui->popupHideSpinBox->setEnabled( m_ui->popupInfoCheckBox->isChecked() );
|
|
m_ui->hideLabel->setEnabled( m_ui->popupInfoCheckBox->isChecked() );
|
|
|
|
// Effect for desktop switching
|
|
// Set current option to "none" if no plugin is activated.
|
|
KConfigGroup effectconfig( m_config, "Plugins" );
|
|
m_ui->effectComboBox->setCurrentIndex( 0 );
|
|
if( effectEnabled( "slide", effectconfig ))
|
|
m_ui->effectComboBox->setCurrentIndex( 1 );
|
|
if( effectEnabled( "cubeslide", effectconfig ))
|
|
m_ui->effectComboBox->setCurrentIndex( 2 );
|
|
if( effectEnabled( "fadedesktop", effectconfig ))
|
|
m_ui->effectComboBox->setCurrentIndex( 3 );
|
|
slotEffectSelectionChanged( m_ui->effectComboBox->currentIndex() );
|
|
// TODO: plasma stuff
|
|
|
|
emit changed(false);
|
|
}
|
|
|
|
void KWinDesktopConfig::save()
|
|
{
|
|
// TODO: plasma stuff
|
|
#ifdef Q_WS_X11
|
|
NETRootInfo info( QX11Info::display(), NET::NumberOfDesktops | NET::DesktopNames );
|
|
// set desktop names
|
|
for( int i = 1; i <= maxDesktops; i++ )
|
|
{
|
|
QString desktopName = m_desktopNames[ i -1 ];
|
|
if( i <= m_ui->numberSpinBox->value() )
|
|
desktopName = m_ui->desktopNames->name( i );
|
|
info.setDesktopName( i, desktopName.toUtf8());
|
|
info.activate();
|
|
}
|
|
// set number of desktops
|
|
info.setNumberOfDesktops( m_ui->numberSpinBox->value() );
|
|
info.activate();
|
|
|
|
XSync(QX11Info::display(), false);
|
|
#endif
|
|
|
|
// Popup info
|
|
KConfigGroup popupInfo( m_config, "PopupInfo" );
|
|
popupInfo.writeEntry( "ShowPopup", m_ui->popupInfoCheckBox->isChecked() );
|
|
popupInfo.writeEntry( "PopupHideDelay", m_ui->popupHideSpinBox->value() );
|
|
|
|
// Effect desktop switching
|
|
KConfigGroup effectconfig( m_config, "Plugins" );
|
|
int desktopSwitcher = m_ui->effectComboBox->currentIndex();
|
|
switch( desktopSwitcher )
|
|
{
|
|
case 0:
|
|
// no effect
|
|
effectconfig.writeEntry("kwin4_effect_slideEnabled", false);
|
|
effectconfig.writeEntry("kwin4_effect_cubeslideEnabled", false);
|
|
effectconfig.writeEntry("kwin4_effect_fadedesktopEnabled", false);
|
|
break;
|
|
case 1:
|
|
// slide
|
|
effectconfig.writeEntry("kwin4_effect_slideEnabled", true);
|
|
effectconfig.writeEntry("kwin4_effect_cubeslideEnabled", false);
|
|
effectconfig.writeEntry("kwin4_effect_fadedesktopEnabled", false);
|
|
break;
|
|
case 2:
|
|
// cube
|
|
effectconfig.writeEntry("kwin4_effect_slideEnabled", false);
|
|
effectconfig.writeEntry("kwin4_effect_cubeslideEnabled", true);
|
|
effectconfig.writeEntry("kwin4_effect_fadedesktopEnabled", false);
|
|
break;
|
|
case 3:
|
|
// fadedesktop
|
|
effectconfig.writeEntry("kwin4_effect_slideEnabled", false);
|
|
effectconfig.writeEntry("kwin4_effect_cubeslideEnabled", false);
|
|
effectconfig.writeEntry("kwin4_effect_fadedesktopEnabled", true);
|
|
break;
|
|
}
|
|
|
|
m_editor->save();
|
|
|
|
m_config->sync();
|
|
// Send signal to all kwin instances
|
|
QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
|
QDBusConnection::sessionBus().send(message);
|
|
|
|
emit changed(false);
|
|
}
|
|
|
|
QString KWinDesktopConfig::cachedDesktopName( int desktop )
|
|
{
|
|
if( desktop > m_desktopNames.size() )
|
|
return QString();
|
|
return m_desktopNames[ desktop -1 ];
|
|
}
|
|
|
|
void KWinDesktopConfig::slotChangeShortcuts( int number )
|
|
{
|
|
if( (number < 1) || (number > maxDesktops) )
|
|
return;
|
|
|
|
if( m_ui->allShortcutsCheckBox->isChecked() )
|
|
number = maxDesktops;
|
|
|
|
while( number != m_actionCollection->count() )
|
|
{
|
|
if( number < m_actionCollection->count() )
|
|
{
|
|
// remove last actions
|
|
m_actionCollection->removeAction( m_actionCollection->actions().last() );
|
|
}
|
|
else
|
|
{
|
|
// add desktop
|
|
int desktop = m_actionCollection->count() + 1;
|
|
KAction* action = qobject_cast<KAction*>(m_actionCollection->addAction(
|
|
"Switch to Desktop " + QString::number(desktop)));
|
|
action->setText( i18n("Switch to Desktop %1", desktop) );
|
|
action->setGlobalShortcut( KShortcut(), KAction::ActiveShortcut );
|
|
switch( desktop )
|
|
{
|
|
case 1:
|
|
action->setGlobalShortcut(KShortcut(Qt::CTRL+Qt::Key_F1), KAction::DefaultShortcut );
|
|
break;
|
|
case 2:
|
|
action->setGlobalShortcut(KShortcut(Qt::CTRL+Qt::Key_F2), KAction::DefaultShortcut );
|
|
break;
|
|
case 3:
|
|
action->setGlobalShortcut(KShortcut(Qt::CTRL+Qt::Key_F3), KAction::DefaultShortcut );
|
|
break;
|
|
case 4:
|
|
action->setGlobalShortcut(KShortcut(Qt::CTRL+Qt::Key_F4), KAction::DefaultShortcut );
|
|
break;
|
|
default:
|
|
// no shortcut
|
|
break;
|
|
}
|
|
action->setProperty("isConfigurationAction", true);
|
|
}
|
|
}
|
|
m_editor->clearCollections();
|
|
m_editor->addCollection( m_switchDesktopCollection, i18n( "Desktop Switching" ) );
|
|
m_editor->addCollection( m_actionCollection, i18n( "Desktop Switching" ) );
|
|
}
|
|
|
|
void KWinDesktopConfig::slotShowAllShortcuts()
|
|
{
|
|
slotChangeShortcuts( m_ui->numberSpinBox->value() );
|
|
}
|
|
|
|
void KWinDesktopConfig::slotEffectSelectionChanged( int index )
|
|
{
|
|
bool enabled = false;
|
|
if( index != 0 )
|
|
enabled = true;
|
|
m_ui->effectInfoButton->setEnabled( enabled );
|
|
// only cube has config dialog
|
|
if( index != 2 )
|
|
enabled = false;
|
|
m_ui->effectConfigButton->setEnabled( enabled );
|
|
}
|
|
|
|
|
|
bool KWinDesktopConfig::effectEnabled( const QString& effect, const KConfigGroup& cfg ) const
|
|
{
|
|
KService::List services = KServiceTypeTrader::self()->query(
|
|
"KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_" + effect + "'");
|
|
if( services.isEmpty())
|
|
return false;
|
|
QVariant v = services.first()->property("X-KDE-PluginInfo-EnabledByDefault");
|
|
return cfg.readEntry("kwin4_effect_" + effect + "Enabled", v.toBool());
|
|
}
|
|
|
|
void KWinDesktopConfig::slotAboutEffectClicked()
|
|
{
|
|
KServiceTypeTrader* trader = KServiceTypeTrader::self();
|
|
KService::List services;
|
|
QString effect;
|
|
switch( m_ui->effectComboBox->currentIndex() )
|
|
{
|
|
case 1:
|
|
effect = "slide";
|
|
break;
|
|
case 2:
|
|
effect = "cubeslide";
|
|
break;
|
|
case 3:
|
|
effect = "fadedesktop";
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
services = trader->query("KWin/Effect", "[X-KDE-PluginInfo-Name] == 'kwin4_effect_" + effect + "'");
|
|
if( services.isEmpty() )
|
|
return;
|
|
KPluginInfo pluginInfo( services.first() );
|
|
|
|
const QString name = pluginInfo.name();
|
|
const QString comment = pluginInfo.comment();
|
|
const QString author = pluginInfo.author();
|
|
const QString email = pluginInfo.email();
|
|
const QString website = pluginInfo.website();
|
|
const QString version = pluginInfo.version();
|
|
const QString license = pluginInfo.license();
|
|
const QString icon = pluginInfo.icon();
|
|
|
|
KAboutData aboutData(name.toUtf8(), name.toUtf8(), ki18n(name.toUtf8()), version.toUtf8(), ki18n(comment.toUtf8()), KAboutLicense::byKeyword(license).key(), ki18n(QByteArray()), ki18n(QByteArray()), website.toLatin1());
|
|
aboutData.setProgramIconName( icon );
|
|
const QStringList authors = author.split(',');
|
|
const QStringList emails = email.split(',');
|
|
int i = 0;
|
|
if( authors.count() == emails.count() )
|
|
{
|
|
foreach( const QString &author, authors )
|
|
{
|
|
if( !author.isEmpty() )
|
|
{
|
|
aboutData.addAuthor(ki18n(author.toUtf8()), ki18n(QByteArray()), emails[i].toUtf8(), 0);
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
KAboutApplicationDialog aboutPlugin( &aboutData, this );
|
|
aboutPlugin.exec();
|
|
}
|
|
|
|
void KWinDesktopConfig::slotConfigureEffectClicked()
|
|
{
|
|
QString effect;
|
|
switch( m_ui->effectComboBox->currentIndex() )
|
|
{
|
|
case 2:
|
|
effect = "cubeslide_config";
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
KCModuleProxy* proxy = new KCModuleProxy( effect );
|
|
KDialog configDialog( this );
|
|
configDialog.setWindowTitle( m_ui->effectComboBox->currentText() );
|
|
configDialog.setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Default );
|
|
connect(&configDialog, SIGNAL(defaultClicked()), proxy, SLOT(defaults()));
|
|
|
|
QWidget *showWidget = new QWidget( &configDialog );
|
|
QVBoxLayout *layout = new QVBoxLayout;
|
|
showWidget->setLayout( layout );
|
|
layout->addWidget( proxy );
|
|
layout->insertSpacing( -1, KDialog::marginHint() );
|
|
configDialog.setMainWidget( showWidget );
|
|
|
|
if( configDialog.exec() == QDialog::Accepted )
|
|
{
|
|
proxy->save();
|
|
}
|
|
else
|
|
{
|
|
proxy->load();
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
#include "main.moc"
|