kwin Library API Documentation

kwindecoration.cpp

00001 /*
00002     This is the new kwindecoration kcontrol module
00003 
00004     Copyright (c) 2001
00005         Karol Szwed <gallium@kde.org>
00006         http://gallium.n3.net/
00007 
00008     Supports new kwin configuration plugins, and titlebar button position
00009     modification via dnd interface.
00010 
00011     Based on original "kwintheme" (Window Borders)
00012     Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
00013 
00014     This program is free software; you can redistribute it and/or modify
00015     it under the terms of the GNU General Public License as published by
00016     the Free Software Foundation; either version 2 of the License, or
00017     (at your option) any later version.
00018 
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022     GNU General Public License for more details.
00023 
00024     You should have received a copy of the GNU General Public License
00025     along with this program; if not, write to the Free Software
00026     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027 
00028 */
00029 
00030 #include <assert.h>
00031 #include <qdir.h>
00032 #include <qfileinfo.h>
00033 #include <qlayout.h>
00034 #include <qwhatsthis.h>
00035 #include <qgroupbox.h>
00036 #include <qcheckbox.h>
00037 #include <qtabwidget.h>
00038 #include <qvbox.h>
00039 #include <qlabel.h>
00040 #include <qfile.h>
00041 #include <qslider.h>
00042 
00043 #include <kapplication.h>
00044 #include <kcombobox.h>
00045 #include <kdebug.h>
00046 #include <kdesktopfile.h>
00047 #include <kstandarddirs.h>
00048 #include <kglobal.h>
00049 #include <klocale.h>
00050 #include <kdialog.h>
00051 #include <kgenericfactory.h>
00052 #include <kaboutdata.h>
00053 #include <dcopclient.h>
00054 
00055 #include "kwindecoration.h"
00056 #include "preview.h"
00057 #include <kdecoration_plugins_p.h>
00058 #include <kdecorationfactory.h>
00059 
00060 // KCModule plugin interface
00061 // =========================
00062 typedef KGenericFactory<KWinDecorationModule, QWidget> KWinDecoFactory;
00063 K_EXPORT_COMPONENT_FACTORY( kcm_kwindecoration, KWinDecoFactory("kcmkwindecoration") )
00064 
00065 KWinDecorationModule::KWinDecorationModule(QWidget* parent, const char* name, const QStringList &)
00066     : DCOPObject("KWinClientDecoration"),
00067       KCModule(KWinDecoFactory::instance(), parent, name),
00068           kwinConfig("kwinrc"),
00069           pluginObject(0)
00070 {
00071     kwinConfig.setGroup("Style");
00072         plugins = new KDecorationPreviewPlugins( &kwinConfig );
00073 
00074     QVBoxLayout* layout = new QVBoxLayout(this);
00075     tabWidget = new QTabWidget( this );
00076     layout->addWidget( tabWidget );
00077 
00078     // Page 1 (General Options)
00079     QWidget *pluginPage = new QWidget( tabWidget );
00080 
00081     QHBox *hbox = new QHBox(pluginPage);
00082     hbox->setSpacing(KDialog::spacingHint());
00083 //  QLabel *lbl = new QLabel( i18n("&Decoration:"), hbox );
00084     decorationList = new KComboBox( hbox );
00085 //  lbl->setBuddy(decorationList);
00086     QString whatsThis = i18n("Select the window decoration. This is the look and feel of both "
00087                              "the window borders and the window handle.");
00088 //  QWhatsThis::add(lbl, whatsThis);
00089     QWhatsThis::add(decorationList, whatsThis);
00090 
00091     QVBoxLayout* pluginLayout = new QVBoxLayout(pluginPage, KDialog::marginHint(), KDialog::spacingHint());
00092     pluginLayout->addWidget(hbox);
00093 
00094 // Save this for later...
00095 //  cbUseMiniWindows = new QCheckBox( i18n( "Render mini &titlebars for all windows"), checkGroup );
00096 //  QWhatsThis::add( cbUseMiniWindows, i18n( "Note that this option is not available on all styles yet!" ) );
00097 
00098     QFrame* preview_frame = new QFrame( pluginPage );
00099     preview_frame->setFrameShape( QFrame::NoFrame );
00100     QVBoxLayout* preview_layout = new QVBoxLayout( preview_frame, 0 );
00101     preview = new KDecorationPreview( preview_frame );
00102     preview_layout->addWidget( preview );
00103     pluginLayout->addWidget( preview_frame );
00104     pluginLayout->setStretchFactor( preview_frame, 10 );
00105 
00106     pluginSettingsGrp = new QGroupBox( i18n("Decoration Options"), pluginPage );
00107     pluginSettingsGrp->setColumnLayout( 0, Vertical );
00108     pluginSettingsGrp->setFlat( true );
00109     pluginSettingsGrp->layout()->setMargin( 0 );
00110     pluginSettingsGrp->layout()->setSpacing( KDialog::spacingHint() );
00111     pluginLayout->addWidget( pluginSettingsGrp );
00112 
00113     pluginConfigWidget = new QVBox(pluginSettingsGrp);
00114     pluginSettingsGrp->layout()->add( pluginConfigWidget );
00115 
00116     // Page 2 (Button Selector)
00117     QVBox* buttonPage = new QVBox( tabWidget );
00118     buttonPage->setSpacing( KDialog::spacingHint() );
00119     buttonPage->setMargin( KDialog::marginHint() );
00120 
00121     cbShowToolTips = new QCheckBox(
00122             i18n("&Show window button tooltips"), buttonPage );
00123     QWhatsThis::add( cbShowToolTips,
00124             i18n(  "Enabling this checkbox will show window button tooltips. "
00125                    "If this checkbox is off, no window button tooltips will be shown."));
00126 
00127         lBorder = new QLabel( buttonPage );
00128         slBorder = new QSlider( Horizontal, buttonPage );
00129         slBorder->setPageStep(1);
00130         QWhatsThis::add( slBorder, i18n( "This slider shows all border sizes supported by this decoration." ));
00131         lBorder->setBuddy( slBorder );
00132         lBorder->hide();
00133         slBorder->hide();
00134 
00135     cbUseCustomButtonPositions = new QCheckBox(
00136             i18n("Use custom titlebar button &positions"), buttonPage );
00137     QWhatsThis::add( cbUseCustomButtonPositions,
00138             i18n(  "The appropriate settings can be found in the \"Buttons\" Tab; "
00139                    "please note that this option is not available on all styles yet." ) );
00140 
00141     buttonBox = new QGroupBox( 1, Qt::Horizontal,
00142             i18n("Titlebar Button Positions"), buttonPage );
00143 
00144     // Add nifty dnd button modification widgets
00145     QLabel* label = new QLabel( buttonBox );
00146     dropSite = new ButtonDropSite( buttonBox );
00147     label->setAlignment( int( QLabel::WordBreak ) );
00148     label->setText( i18n( "To add or remove titlebar buttons, simply <i>drag</i> items "
00149         "between the available item list and the titlebar preview. Similarly, "
00150         "drag items within the titlebar preview to re-position them.") );
00151     buttonSource = new ButtonSource( buttonBox );
00152 
00153     // Load all installed decorations into memory
00154     // Set up the decoration lists and other UI settings
00155     findDecorations();
00156     createDecorationList();
00157     readConfig( &kwinConfig );
00158     resetPlugin( &kwinConfig );
00159 
00160     tabWidget->insertTab( pluginPage, i18n("&Window Decoration") );
00161     tabWidget->insertTab( buttonPage, i18n("&Buttons") );
00162 
00163     connect( dropSite, SIGNAL(buttonAdded(char)), buttonSource, SLOT(hideButton(char)) );
00164     connect( dropSite, SIGNAL(buttonRemoved(char)), buttonSource, SLOT(showButton(char)) );
00165     connect( buttonSource, SIGNAL(buttonDropped()), dropSite, SLOT(removeClickedButton()) );
00166     connect( dropSite, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) );
00167     connect( buttonSource, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
00168     connect( decorationList, SIGNAL(activated(const QString&)), SLOT(slotSelectionChanged()) );
00169     connect( decorationList, SIGNAL(activated(const QString&)),
00170                                 SLOT(slotChangeDecoration(const QString&)) );
00171     connect( cbUseCustomButtonPositions, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
00172     connect(cbUseCustomButtonPositions, SIGNAL(toggled(bool)), buttonBox, SLOT(setEnabled(bool)));
00173     connect( cbShowToolTips, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
00174         connect( slBorder, SIGNAL( valueChanged( int )), SLOT( slotBorderChanged( int )));
00175 //  connect( cbUseMiniWindows, SIGNAL(clicked()), SLOT(slotSelectionChanged()) );
00176 
00177     // Allow kwin dcop signal to update our selection list
00178     connectDCOPSignal("kwin", 0, "dcopResetAllClients()", "dcopUpdateClientList()", false);
00179     
00180     KAboutData *about =
00181         new KAboutData(I18N_NOOP("kcmkwindecoration"),
00182                 I18N_NOOP("Window Decoration Control Module"),
00183                 0, 0, KAboutData::License_GPL,
00184                 I18N_NOOP("(c) 2001 Karol Szwed"));
00185     about->addAuthor("Karol Szwed", 0, "gallium@kde.org");
00186     setAboutData(about);
00187 }
00188 
00189 
00190 KWinDecorationModule::~KWinDecorationModule()
00191 {
00192         delete preview; // needs to be destroyed before plugins
00193         delete plugins;
00194 }
00195 
00196 
00197 // Find all theme desktop files in all 'data' dirs owned by kwin.
00198 // And insert these into a DecorationInfo structure
00199 void KWinDecorationModule::findDecorations()
00200 {
00201     QStringList dirList = KGlobal::dirs()->findDirs("data", "kwin");
00202     QStringList::ConstIterator it;
00203 
00204     for (it = dirList.begin(); it != dirList.end(); it++)
00205     {
00206         QDir d(*it);
00207         if (d.exists())
00208             for (QFileInfoListIterator it(*d.entryInfoList()); it.current(); ++it)
00209             {
00210                 QString filename(it.current()->absFilePath());
00211                 if (KDesktopFile::isDesktopFile(filename))
00212                 {
00213                     KDesktopFile desktopFile(filename);
00214                     QString libName = desktopFile.readEntry("X-KDE-Library");
00215 
00216                     if (!libName.isEmpty() && libName.startsWith( "kwin3_" ))
00217                     {
00218                         DecorationInfo di;
00219                         di.name = desktopFile.readName();
00220                         di.libraryName = libName;
00221                         decorations.append( di );
00222                     }
00223                 }
00224             }
00225     }
00226 }
00227 
00228 
00229 // Fills the decorationList with a list of available kwin decorations
00230 void KWinDecorationModule::createDecorationList()
00231 {
00232     QValueList<DecorationInfo>::ConstIterator it;
00233 
00234     // Sync with kwin hardcoded KDE2 style which has no desktop item
00235     QStringList decorationNames;
00236     decorationNames.append( i18n("KDE 2") );
00237     for (it = decorations.begin(); it != decorations.end(); ++it)
00238     {
00239         decorationNames.append((*it).name);
00240     }
00241     decorationNames.sort();
00242     decorationList->insertStringList(decorationNames);
00243 }
00244 
00245 
00246 // Reset the decoration plugin to what the user just selected
00247 void KWinDecorationModule::slotChangeDecoration( const QString & text)
00248 {
00249     KConfig kwinConfig("kwinrc");
00250     kwinConfig.setGroup("Style");
00251 
00252     // Let the user see config options for the currently selected decoration
00253     resetPlugin( &kwinConfig, text );
00254 }
00255 
00256 
00257 // This is the selection handler setting
00258 void KWinDecorationModule::slotSelectionChanged()
00259 {
00260     emit KCModule::changed(true);
00261 }
00262 
00263 static const char* const border_names[ KDecorationDefines::BordersCount ] =
00264     {
00265     I18N_NOOP( "Border size: Tiny" ),
00266     I18N_NOOP( "Border size: Normal" ),
00267     I18N_NOOP( "Border size: Large" ),
00268     I18N_NOOP( "Border size: Very Large" ),
00269     I18N_NOOP( "Border size: Huge" ),
00270     I18N_NOOP( "Border size: Very Huge" ),
00271     I18N_NOOP( "Border size: Oversized" )
00272     };
00273 
00274 int KWinDecorationModule::borderSizeToIndex( BorderSize size, QValueList< BorderSize > sizes )
00275 {
00276         int pos = 0;
00277         for( QValueList< BorderSize >::ConstIterator it = sizes.begin();
00278              it != sizes.end();
00279              ++it, ++pos )
00280             if( size <= *it )
00281                 break;
00282         return pos;
00283 }
00284 
00285 KDecorationDefines::BorderSize KWinDecorationModule::indexToBorderSize( int index,
00286     QValueList< BorderSize > sizes )
00287 {
00288         QValueList< BorderSize >::ConstIterator it = sizes.begin();
00289         for(;
00290              it != sizes.end();
00291              ++it, --index )
00292             if( index == 0 )
00293                 break;
00294         return *it;
00295 }
00296 
00297 void KWinDecorationModule::slotBorderChanged( int size )
00298 {
00299         if( lBorder->isHidden())
00300             return;
00301         emit KCModule::changed( true );
00302         QValueList< BorderSize > sizes;
00303         if( plugins->factory() != NULL )
00304             sizes = plugins->factory()->borderSizes();
00305         assert( sizes.count() >= 2 );
00306         border_size = indexToBorderSize( size, sizes );
00307         lBorder->setText( i18n( border_names[ border_size ] ));
00308 }
00309 
00310 QString KWinDecorationModule::decorationName( QString& libName )
00311 {
00312     QString decoName;
00313 
00314     QValueList<DecorationInfo>::Iterator it;
00315     for( it = decorations.begin(); it != decorations.end(); ++it )
00316         if ( (*it).libraryName == libName )
00317         {
00318             decoName = (*it).name;
00319             break;
00320         }
00321 
00322     return decoName;
00323 }
00324 
00325 
00326 QString KWinDecorationModule::decorationLibName( const QString& name )
00327 {
00328     QString libName;
00329 
00330     // Find the corresponding library name to that of
00331     // the current plugin name
00332     QValueList<DecorationInfo>::Iterator it;
00333     for( it = decorations.begin(); it != decorations.end(); ++it )
00334         if ( (*it).name == name )
00335         {
00336             libName = (*it).libraryName;
00337             break;
00338         }
00339 
00340     if (libName.isEmpty())
00341         libName = "kwin_default";   // KDE 2
00342 
00343     return libName;
00344 }
00345 
00346 
00347 // Loads/unloads and inserts the decoration config plugin into the
00348 // pluginConfigWidget, allowing for dynamic configuration of decorations
00349 void KWinDecorationModule::resetPlugin( KConfig* conf, const QString& currentDecoName )
00350 {
00351     // Config names are "kwin_icewm_config"
00352     // for "kwin3_icewm" kwin client
00353 
00354     QString oldName = styleToConfigLib( oldLibraryName );
00355 
00356     QString currentName;
00357     if (!currentDecoName.isEmpty())
00358         currentName = decorationLibName( currentDecoName ); // Use what the user selected
00359     else
00360         currentName = currentLibraryName; // Use what was read from readConfig()
00361 
00362         if( plugins->loadPlugin( currentName )
00363             && preview->recreateDecoration( plugins ))
00364             preview->enablePreview();
00365         else
00366             preview->disablePreview();
00367         plugins->destroyPreviousPlugin();
00368 
00369         checkSupportedBorderSizes();
00370 
00371     currentName = styleToConfigLib( currentName );
00372 
00373     // Delete old plugin widget if it exists
00374     delete pluginObject;
00375     pluginObject = 0;
00376 
00377     // Use klibloader for library manipulation
00378     KLibLoader* loader = KLibLoader::self();
00379 
00380     // Free the old library if possible
00381     if (!oldLibraryName.isNull())
00382         loader->unloadLibrary( QFile::encodeName(oldName) );
00383 
00384     KLibrary* library = loader->library( QFile::encodeName(currentName) );
00385     if (library != NULL)
00386     {
00387         void* alloc_ptr = library->symbol("allocate_config");
00388 
00389         if (alloc_ptr != NULL)
00390         {
00391             allocatePlugin = (QObject* (*)(KConfig* conf, QWidget* parent))alloc_ptr;
00392             pluginObject = (QObject*)(allocatePlugin( conf, pluginConfigWidget ));
00393 
00394             // connect required signals and slots together...
00395             connect( pluginObject, SIGNAL(changed()), this, SLOT(slotSelectionChanged()) );
00396             connect( this, SIGNAL(pluginLoad(KConfig*)), pluginObject, SLOT(load(KConfig*)) );
00397             connect( this, SIGNAL(pluginSave(KConfig*)), pluginObject, SLOT(save(KConfig*)) );
00398             connect( this, SIGNAL(pluginDefaults()), pluginObject, SLOT(defaults()) );
00399             pluginSettingsGrp->show();
00400             return;
00401         }
00402     }
00403 
00404     pluginSettingsGrp->hide();
00405 }
00406 
00407 
00408 // Reads the kwin config settings, and sets all UI controls to those settings
00409 // Updating the config plugin if required
00410 void KWinDecorationModule::readConfig( KConfig* conf )
00411 {
00412     // General tab
00413     // ============
00414     cbShowToolTips->setChecked( conf->readBoolEntry("ShowToolTips", true ));
00415 //  cbUseMiniWindows->setChecked( conf->readBoolEntry("MiniWindowBorders", false));
00416 
00417     // Find the corresponding decoration name to that of
00418     // the current plugin library name
00419 
00420     oldLibraryName = currentLibraryName;
00421     currentLibraryName = conf->readEntry("PluginLib",
00422                     ((QPixmap::defaultDepth() > 8) ? "kwin3_mandrake2" : "kwin_quartz"));
00423     QString decoName = decorationName( currentLibraryName );
00424 
00425     // If we are using the "default" kde client, use the "default" entry.
00426     if (decoName.isEmpty())
00427         decoName = i18n("KDE 2");
00428 
00429     int numDecos = decorationList->count();
00430     for (int i = 0; i < numDecos; ++i)
00431     {
00432          if (decorationList->text(i) == decoName)
00433          {
00434                  decorationList->setCurrentItem(i);
00435                  break;
00436          }
00437     }
00438 
00439     // Buttons tab
00440     // ============
00441     bool customPositions = conf->readBoolEntry("CustomButtonPositions", false);
00442     cbUseCustomButtonPositions->setChecked( customPositions );
00443     buttonBox->setEnabled( customPositions );
00444     // Menu and onAllDesktops buttons are default on LHS
00445     dropSite->buttonsLeft  = conf->readEntry("ButtonsOnLeft", "MS");
00446     // Help, Minimize, Maximize and Close are default on RHS
00447     dropSite->buttonsRight = conf->readEntry("ButtonsOnRight", "HIAX");
00448     dropSite->repaint(false);
00449 
00450     buttonSource->showAllButtons();
00451 
00452     // Step through the button lists, and hide the dnd button source items
00453     unsigned int i;
00454     for(i = 0; i < dropSite->buttonsLeft.length(); i++)
00455         buttonSource->hideButton( dropSite->buttonsLeft[i].latin1() );
00456     for(i = 0; i < dropSite->buttonsRight.length(); i++)
00457         buttonSource->hideButton( dropSite->buttonsRight[i].latin1() );
00458 
00459         int bsize = conf->readNumEntry( "BorderSize", BorderNormal );
00460         if( bsize >= BorderTiny && bsize < BordersCount )
00461             border_size = static_cast< BorderSize >( bsize );
00462         else
00463             border_size = BorderNormal;
00464         checkSupportedBorderSizes();
00465 
00466     emit KCModule::changed(false);
00467 }
00468 
00469 
00470 // Writes the selected user configuration to the kwin config file
00471 void KWinDecorationModule::writeConfig( KConfig* conf )
00472 {
00473     QString name = decorationList->currentText();
00474     QString libName = decorationLibName( name );
00475 
00476     KConfig kwinConfig("kwinrc");
00477     kwinConfig.setGroup("Style");
00478 
00479     // General settings
00480     conf->writeEntry("PluginLib", libName);
00481     conf->writeEntry("CustomButtonPositions", cbUseCustomButtonPositions->isChecked());
00482     conf->writeEntry("ShowToolTips", cbShowToolTips->isChecked());
00483 //  conf->writeEntry("MiniWindowBorders", cbUseMiniWindows->isChecked());
00484 
00485     // Button settings
00486     conf->writeEntry("ButtonsOnLeft", dropSite->buttonsLeft );
00487     conf->writeEntry("ButtonsOnRight", dropSite->buttonsRight );
00488         conf->writeEntry("BorderSize", border_size );
00489 
00490     oldLibraryName = currentLibraryName;
00491     currentLibraryName = libName;
00492 
00493     // We saved, so tell kcmodule that there have been  no new user changes made.
00494     emit KCModule::changed(false);
00495 }
00496 
00497 
00498 void KWinDecorationModule::dcopUpdateClientList()
00499 {
00500     // Changes the current active ListBox item, and
00501     // Loads a new plugin configuration tab if required.
00502     KConfig kwinConfig("kwinrc");
00503     kwinConfig.setGroup("Style");
00504 
00505     readConfig( &kwinConfig );
00506     resetPlugin( &kwinConfig );
00507 }
00508 
00509 
00510 // Virutal functions required by KCModule
00511 void KWinDecorationModule::load()
00512 {
00513     KConfig kwinConfig("kwinrc");
00514     kwinConfig.setGroup("Style");
00515 
00516     // Reset by re-reading the config
00517     readConfig( &kwinConfig );
00518         resetPlugin( &kwinConfig );
00519 }
00520 
00521 
00522 void KWinDecorationModule::save()
00523 {
00524     KConfig kwinConfig("kwinrc");
00525     kwinConfig.setGroup("Style");
00526 
00527     writeConfig( &kwinConfig );
00528     emit pluginSave( &kwinConfig );
00529 
00530     kwinConfig.sync();
00531     resetKWin();
00532     // resetPlugin() will get called via the above DCOP function
00533 }
00534 
00535 
00536 void KWinDecorationModule::defaults()
00537 {
00538     // Set the KDE defaults
00539     cbUseCustomButtonPositions->setChecked( false );
00540     buttonBox->setEnabled( false );
00541     cbShowToolTips->setChecked( true );
00542 //  cbUseMiniWindows->setChecked( false);
00543 // Don't set default for now
00544 //  decorationList->setSelected(
00545 //      decorationList->findItem( i18n("KDE 2") ), true );  // KDE classic client
00546 
00547     dropSite->buttonsLeft = "MS";
00548     dropSite->buttonsRight= "HIAX";
00549     dropSite->repaint(false);
00550 
00551     buttonSource->showAllButtons();
00552     buttonSource->hideButton('M');
00553     buttonSource->hideButton('S');
00554     buttonSource->hideButton('H');
00555     buttonSource->hideButton('I');
00556     buttonSource->hideButton('A');
00557     buttonSource->hideButton('X');
00558 
00559         border_size = BorderNormal;
00560         checkSupportedBorderSizes();
00561 
00562     // Set plugin defaults
00563     emit pluginDefaults();
00564 }
00565 
00566 void KWinDecorationModule::checkSupportedBorderSizes()
00567 {
00568         QValueList< BorderSize > sizes;
00569         slBorder->hide();
00570         lBorder->hide();
00571         if( plugins->factory() != NULL )
00572             sizes = plugins->factory()->borderSizes();
00573         if( sizes.count() < 2 )
00574             return;
00575         slBorder->setRange( 0, sizes.count() - 1 );
00576         int pos = borderSizeToIndex( border_size, sizes );
00577         lBorder->show();
00578         slBorder->show();
00579         slBorder->setValue( pos );
00580         slotBorderChanged( pos );
00581 }
00582 
00583 QString KWinDecorationModule::styleToConfigLib( QString& styleLib )
00584 {
00585         if( styleLib.startsWith( "kwin3_" ))
00586             return "kwin_" + styleLib.mid( 6 ) + "_config";
00587         else
00588             return styleLib + "_config";
00589 }
00590 
00591 QString KWinDecorationModule::quickHelp() const
00592 {
00593     return i18n( "<h1>Window Manager Decoration</h1>"
00594         "<p>This module allows you to choose the window border decorations, "
00595         "as well as titlebar button positions and custom decoration options.</p>"
00596         "To choose a theme for your window decoration click on its name and apply your choice by clicking the \"Apply\" button below."
00597         " If you don't want to apply your choice you can click the \"Reset\" button to discard your changes."
00598         "<p>You can configure each theme in the \"Configure [...]\" tab. There are different options specific for each theme.</p>"
00599         "<p>In \"General Options (if available)\" you can activate the \"Buttons\" tab by checking the \"Use custom titlebar button positions\" box."
00600         " In the \"Buttons\" tab you can change the positions of the buttons to your liking.</p>" );
00601 }
00602 
00603 
00604 void KWinDecorationModule::resetKWin()
00605 {
00606     bool ok = kapp->dcopClient()->send("kwin", "KWinInterface",
00607                         "reconfigure()", QByteArray());
00608     if (!ok)
00609         kdDebug() << "kcmkwindecoration: Could not reconfigure kwin" << endl;
00610 }
00611 
00612 #include "kwindecoration.moc"
00613 // vim: ts=4
00614 
KDE Logo
This file is part of the documentation for kwin Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 5 03:59:39 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003