Default style update:

- Modifying the default style to use the new kwin plugin interface for proper
  resource management.
- The new default style looks nearly the same, but adds several nice features
  such as titlebar height and button position customisation among others,
  and adds a config module for configuration.
- kwin plugin loader modified to reflect the new default plugin change. The
  old default will be removed shortly.
- oh, and never ever flicker :)

svn path=/trunk/kdebase/kwin/; revision=100839
This commit is contained in:
Karol Szwed 2001-06-07 11:35:06 +00:00
parent 7afe6d11c7
commit 97b0ee49e1
10 changed files with 1525 additions and 146 deletions

View file

@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/kwin/default $(all_includes)
SUBDIRS = default . pics clients
SUBDIRS = . pics clients
bin_PROGRAMS = kwin
lib_LTLIBRARIES = kwin.la
@ -9,7 +9,7 @@ lib_LTLIBRARIES = kwin.la
kwin_la_SOURCES = workspace.cpp atoms.cpp client.cpp main.cpp \
tabbox.cpp options.cpp plugins.cpp events.cpp KWinInterface.skel \
killwindow.cpp
kwin_la_LIBADD = $(LIB_KDEUI) $(top_builddir)/kwin/default/libkwindefault.la
kwin_la_LIBADD = $(LIB_KDEUI)
kwin_la_LDFLAGS = $(all_libraries) -module -avoid-version
include_HEADERS = KWinInterface.h

View file

@ -1 +1 @@
SUBDIRS = kde1 kstep system b2 laptop riscos modernsystem win2k kwmtheme quartz icewm web mwm
SUBDIRS = default kde1 kstep system b2 laptop riscos modernsystem win2k kwmtheme quartz icewm web mwm

View file

@ -0,0 +1,17 @@
INCLUDES = $(all_includes)
SUBDIRS = . config
kde_module_LTLIBRARIES = libkwindefault.la
libkwindefault_la_SOURCES = kdedefault.cpp
libkwindefault_la_LIBADD = ../../kwin.la
libkwindefault_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)
METASOURCES = AUTO
noinst_HEADERS = kdedefault.h
###KMAKE-start (don't edit or delete this block)
###KMAKE-end

View file

@ -0,0 +1,16 @@
INCLUDES = $(all_includes)
kde_module_LTLIBRARIES = libkwindefault_config.la
libkwindefault_config_la_SOURCES = config.cpp
libkwindefault_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)
libkwindefault_config_la_LIBADD = $(LIB_KDEUI)
METASOURCES = AUTO
noinst_HEADERS = config.h
lnkdir = $(kde_datadir)/kwin/
###KMAKE-start (don't edit or delete this block)
###KMAKE-end

View file

@ -0,0 +1,161 @@
/*
* $Id$
*
* KDE2 Default configuration widget
*
* Copyright (c) 2001
* Karol Szwed <gallium@kde.org>
* http://gallium.n3.net/
*/
#include "config.h"
#include <qwhatsthis.h>
#include <klocale.h>
#include <qpixmap.h>
extern "C"
{
QObject* allocate_config( KConfig* conf, QWidget* parent )
{
return(new KDEDefaultConfig(conf, parent));
}
}
// NOTE:
// 'conf' is a pointer to the kwindecoration modules open kwin config,
// and is by default set to the "Style" group.
// 'parent' is the parent of the QObject, which is a VBox inside the
// Configure tab in kwindecoration
KDEDefaultConfig::KDEDefaultConfig( KConfig* conf, QWidget* parent )
: QObject( parent )
{
highcolor = QPixmap::defaultDepth() > 8;
gb = new QGroupBox( 1, Qt::Horizontal,
i18n("KDE2 Default Decoration Settings"), parent );
cbShowStipple = new QCheckBox( i18n("Draw titlebar &stipple effect"), gb );
QWhatsThis::add( cbShowStipple,
i18n("When selected, active titlebars are drawn "
"with a stipple (dotted) effect. Otherwise, they are "
"drawn without the stipple."));
cbShowGrabBar = new QCheckBox( i18n("Draw g&rab bar below windows"), gb );
QWhatsThis::add( cbShowGrabBar,
i18n("When selected, decorations are drawn with a \"grab bar\" "
"below windows. Otherwise, no grab bar is drawn."));
// Only show the gradient checkbox for highcolor displays
if (highcolor)
{
cbUseGradients = new QCheckBox( i18n("Draw gr&adients"), gb );
QWhatsThis::add( cbUseGradients,
i18n("When selected, decorations are drawn with gradients "
"for highcolor displays, otherwise no gradients are drawn.") );
}
// Allow titlebar height customization
gbSlider = new QGroupBox( 1, Qt::Horizontal, i18n("TitleBar Height"), gb );
titleBarSizeSlider = new QSlider(0, 2, 1, 0, QSlider::Horizontal, gbSlider);
QWhatsThis::add( titleBarSizeSlider,
i18n("By adjusting this slider, you can modify "
"the height of the titlebar to make room for larger fonts."));
hbox = new QHBox(gbSlider);
hbox->setSpacing(6);
label1 = new QLabel( i18n("Normal"), hbox );
label2 = new QLabel( i18n("Large"), hbox );
label2->setAlignment( AlignHCenter );
label3 = new QLabel( i18n("Huge"), hbox );
label3->setAlignment( AlignRight );
// Load configuration options
load( conf );
// Ensure we track user changes properly
connect( cbShowStipple, SIGNAL(clicked()),
this, SLOT(slotSelectionChanged()) );
connect( cbShowGrabBar, SIGNAL(clicked()),
this, SLOT(slotSelectionChanged()) );
connect( titleBarSizeSlider, SIGNAL(valueChanged(int)),
this, SLOT(slotSelectionChanged(int)) );
if (highcolor)
connect( cbUseGradients, SIGNAL(clicked()),
this, SLOT(slotSelectionChanged()) );
// Make the widgets visible in kwindecoration
gb->show();
}
KDEDefaultConfig::~KDEDefaultConfig()
{
delete gb;
}
void KDEDefaultConfig::slotSelectionChanged()
{
emit changed();
}
void KDEDefaultConfig::slotSelectionChanged(int)
{
emit changed();
}
// Loads the configurable options from the kwinrc config file
// It is passed the open config from kwindecoration to improve efficiency
void KDEDefaultConfig::load( KConfig* conf )
{
conf->setGroup("KDEDefault");
bool override = conf->readBoolEntry( "ShowTitleBarStipple", true );
cbShowStipple->setChecked( override );
override = conf->readBoolEntry( "ShowGrabBar", true );
cbShowGrabBar->setChecked( override );
if (highcolor) {
override = conf->readBoolEntry( "UseGradients", true );
cbUseGradients->setChecked( override );
}
int size = conf->readNumEntry( "TitleBarSize", 0 );
if (size < 0) size = 0;
if (size > 2) size = 2;
titleBarSizeSlider->setValue(size);
}
// Saves the configurable options to the kwinrc config file
void KDEDefaultConfig::save( KConfig* conf )
{
conf->setGroup("KDEDefault");
conf->writeEntry( "ShowTitleBarStipple", cbShowStipple->isChecked() );
conf->writeEntry( "ShowGrabBar", cbShowGrabBar->isChecked() );
if (highcolor)
conf->writeEntry( "UseGradients", cbUseGradients->isChecked() );
conf->writeEntry( "TitleBarSize", titleBarSizeSlider->value() );
// No need to conf->sync() - kwindecoration will do it for us
}
// Sets UI widget defaults which must correspond to style defaults
void KDEDefaultConfig::defaults()
{
cbShowStipple->setChecked( true );
cbShowGrabBar->setChecked( true );
if (highcolor)
cbUseGradients->setChecked( true );
titleBarSizeSlider->setValue(0);
}
#include "config.moc"
// vim: ts=4

View file

@ -0,0 +1,57 @@
/*
* $Id$
*
* KDE2 Default configuration widget
*
* Copyright (c) 2001
* Karol Szwed <gallium@kde.org>
* http://gallium.n3.net/
*/
#ifndef _KDE_DEFAULT_CONFIG_H
#define _KDE_DEFAULT_CONFIG_H
#include <qcheckbox.h>
#include <qgroupbox.h>
#include <kconfig.h>
#include <qslider.h>
#include <qhbox.h>
#include <qlabel.h>
class KDEDefaultConfig: public QObject
{
Q_OBJECT
public:
KDEDefaultConfig( KConfig* conf, QWidget* parent );
~KDEDefaultConfig();
// These public signals/slots work similar to KCM modules
signals:
void changed();
public slots:
void load( KConfig* conf );
void save( KConfig* conf );
void defaults();
protected slots:
void slotSelectionChanged(); // Internal use
void slotSelectionChanged(int); // Internal use
private:
QCheckBox* cbShowStipple;
QCheckBox* cbShowGrabBar;
QCheckBox* cbUseGradients;
QSlider* titleBarSizeSlider;
QGroupBox* gb;
bool highcolor;
QLabel* label1;
QLabel* label2;
QLabel* label3;
QGroupBox* gbSlider;
QHBox* hbox;
};
#endif
// vim: ts=4

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,115 @@
/*
* $Id$
*
* KDE2 Default KWin client
*
* Copyright (C) 1999, 2001 Daniel Duley <mosfet@kde.org>
* Matthias Ettrich <ettrich@kde.org>
* Karol Szwed <gallium@kde.org>
*
* Draws mini titlebars for tool windows.
* Many features are now customizable.
*/
#ifndef _KDE_DEFAULT_H
#define _KDE_DEFAULT_H
#include <qbutton.h>
#include <qbitmap.h>
#include <kpixmap.h>
#include "../../client.h"
class QSpacerItem;
class QHBoxLayout;
namespace KWinInternal {
class KDEDefaultHandler: public QObject
{
public:
KDEDefaultHandler();
~KDEDefaultHandler();
void reset();
private:
void readConfig();
void createPixmaps();
void freePixmaps();
void drawButtonBackground(KPixmap *pix, const QColorGroup &g, bool sunken);
};
class KDEDefaultButton : public QButton
{
public:
KDEDefaultButton(Client *parent=0, const char *name=0, bool largeButton=true,
bool isLeftButton=true, bool isStickyButton=false,
const unsigned char *bitmap=NULL);
~KDEDefaultButton();
void setBitmap(const unsigned char *bitmap);
QSize sizeHint() const;
int last_button;
void turnOn( bool isOn );
protected:
void enterEvent(QEvent *){ isMouseOver=true; repaint(false); }
void leaveEvent(QEvent *){ isMouseOver=false; repaint(false); }
void mousePressEvent( QMouseEvent* e );
void mouseReleaseEvent( QMouseEvent* e );
void drawButton(QPainter *p);
void drawButtonLabel(QPainter*) {;}
Client* client;
QBitmap* deco;
bool large;
bool isLeft;
bool isSticky;
bool isMouseOver;
};
class KDEDefaultClient : public KWinInternal::Client
{
Q_OBJECT
public:
KDEDefaultClient( Workspace *ws, WId w, QWidget *parent=0,
const char *name=0 );
~KDEDefaultClient() {;}
protected:
void resizeEvent( QResizeEvent* );
void paintEvent( QPaintEvent* );
void showEvent( QShowEvent* );
void mouseDoubleClickEvent( QMouseEvent * );
void captionChange( const QString& name );
void maximizeChange(bool m);
void activeChange(bool);
void iconChange();
void stickyChange(bool on);
MousePosition mousePosition(const QPoint &) const;
protected slots:
void slotMaximize();
void menuButtonPressed();
private:
void doShape();
void calcHiddenButtons();
void addClientButtons( const QString& s, bool isLeft=true );
enum Buttons{ BtnHelp=0, BtnMax, BtnIconify, BtnClose,
BtnMenu, BtnSticky, BtnCount };
KDEDefaultButton* button[ KDEDefaultClient::BtnCount ];
int lastButtonWidth;
int titleHeight;
bool largeButtons;
QHBoxLayout* hb;
QSpacerItem* titlebar;
};
};
#endif
// vim: ts=4

View file

@ -18,7 +18,6 @@ Copyright (C) 1999, 2000 Daniel M. Duley <mosfet@kde.org>
#include <qfile.h>
#include "plugins.h"
#include "kdedefault.h"
#if 0
#define lt_ptr lt_ptr_t
@ -26,168 +25,112 @@ Copyright (C) 1999, 2000 Daniel M. Duley <mosfet@kde.org>
using namespace KWinInternal;
PluginMenu::PluginMenu(PluginMgr *manager, QWidget *parent, const char *name)
: QPopupMenu(parent, name)
{
connect(this, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()));
connect(this, SIGNAL(activated(int)), SLOT(slotActivated(int)));
mgr = manager;
}
const char* defaultPlugin = "libkwindefault";
void PluginMenu::slotAboutToShow()
{
clear();
fileList.clear();
insertItem(i18n("KDE 2"), 0);
idCount = 1;
idCurrent = 0;
QDir dir;
dir.setFilter(QDir::Files);
const QFileInfoList *list;
int count = KGlobal::dirs()->findDirs("data", "kwin").count();
if(count){
dir.setPath(KGlobal::dirs()->findDirs("data", "kwin")
[count > 1 ? 1 : 0]);
if(dir.exists()){
list = dir.entryInfoList();
if(list){
QFileInfoListIterator it(*list);
QFileInfo *fi;
for(; (fi = it.current()) != NULL; ++it){
if(KDesktopFile::isDesktopFile(fi->absFilePath()))
parseDesktop(fi);
}
}
}
if(count > 1){
dir.setPath(KGlobal::dirs()->findDirs("data", "kwin")[0]);
if(dir.exists()){
list = dir.entryInfoList();
if(list){
QFileInfoListIterator it(*list);
QFileInfo *fi;
for(; (fi = it.current()) != NULL; ++it){
if(KDesktopFile::isDesktopFile(fi->absFilePath()))
parseDesktop(fi);
}
}
}
}
}
setItemChecked(idCurrent, true);
}
void PluginMenu::parseDesktop(QFileInfo *fi)
{
QString tmpStr;
KSimpleConfig config(fi->absFilePath(), true);
config.setDesktopGroup();
tmpStr = config.readEntry("X-KDE-Library", "");
if(tmpStr.isEmpty()){
qWarning("KWin: Invalid plugin: %s", fi->absFilePath().latin1());
return;
}
fileList.append(tmpStr);
if (tmpStr == mgr->currentPlugin())
idCurrent = idCount;
tmpStr = config.readEntry("Name", "");
if(tmpStr.isEmpty())
tmpStr = fi->baseName();
insertItem(tmpStr, idCount);
++idCount;
}
void PluginMenu::slotActivated(int id)
{
QString newPlugin;
if (id > 0)
newPlugin = fileList[id-1];
KConfig *config = KGlobal::config();
config->setGroup("Style");
config->writeEntry("PluginLib", newPlugin);
config->sync();
// We can't do this directly because we might destruct a client
// underneath our own feet while doing so.
QTimer::singleShot(0, mgr, SLOT(updatePlugin()));
}
PluginMgr::PluginMgr()
: QObject()
{
alloc_ptr = NULL;
handle = 0;
pluginStr = "standard";
pluginStr = "kwin_undefined";
updatePlugin();
}
PluginMgr::~PluginMgr()
{
if(handle)
if(handle) {
// Call the plugin's cleanup function
lt_ptr_t deinit_func = lt_dlsym(handle, "deinit");
if (deinit_func)
((void (*)())deinit_func)();
lt_dlclose(handle);
}
}
bool
PluginMgr::updatePlugin()
void PluginMgr::updatePlugin()
{
KConfig *config = KGlobal::config();
config->reparseConfiguration();
config->setGroup("Style");
QString newPlugin = config->readEntry("PluginLib", "standard" );
if (newPlugin != pluginStr) {
loadPlugin(newPlugin);
return true;
}
return false;
QString newPlugin = config->readEntry("PluginLib", defaultPlugin);
if (newPlugin != pluginStr)
loadPlugin(newPlugin);
}
Client* PluginMgr::allocateClient(Workspace *ws, WId w, bool tool)
{
if(alloc_ptr)
// We are guaranteed to have a plugin loaded,
// otherwise, kwin exits during loadPlugin - but verify anyway
if (alloc_ptr)
return(alloc_ptr(ws, w, tool));
else
return(new KDEClient(ws, w));
return NULL;
}
// returns true if plugin was loaded successfully
void PluginMgr::loadPlugin(QString nameStr)
{
static bool dlregistered = false;
lt_dlhandle oldHandle = handle;
pluginStr = "standard";
handle = 0;
alloc_ptr = 0;
if ( !nameStr.isEmpty() && nameStr != "standard" ) {
if(!dlregistered){
dlregistered = true;
lt_dlinit();
}
QString path = KLibLoader::findLibrary(nameStr.latin1());
if( !path.isEmpty() ) {
if ( (handle = lt_dlopen(path.latin1() ) ) ) {
lt_ptr_t init_func = lt_dlsym(handle, "init");
if (init_func)
((void (*)())init_func)();
lt_ptr_t alloc_func = lt_dlsym(handle, "allocate");
if(alloc_func) {
alloc_ptr = (Client* (*)(Workspace *ws, WId w, int tool))alloc_func;
} else{
qWarning("KWin: %s is not a KWin plugin.", path.latin1());
lt_dlclose(handle);
handle = 0;
}
} else {
qWarning("KWin: cannot load client plugin %s.", path.latin1());
}
}
if(!dlregistered) {
dlregistered = true;
lt_dlinit();
}
if ( alloc_ptr )
pluginStr = nameStr;
QString path = KLibLoader::findLibrary(nameStr.latin1());
// If the plugin was not found, try to find the default
if (path.isEmpty()) {
nameStr = defaultPlugin;
path = KLibLoader::findLibrary(nameStr.latin1());
}
// If no library was found, exit kwin with an error message
if (path.isEmpty())
shutdownKWin(i18n("No window decoration plugin library was found!"));
// Check if this library is not already loaded.
if(pluginStr == nameStr)
return;
// Try loading the requested plugin
handle = lt_dlopen(path.latin1());
// If that fails, fall back to the default plugin
if (!handle) {
nameStr = defaultPlugin;
path = KLibLoader::findLibrary(nameStr.latin1());
if (!path.isEmpty())
handle = lt_dlopen(path.latin1());
}
if (!handle)
shutdownKWin(i18n("The default decoration plugin is corrupt "
"and could not be loaded!"));
// Call the plugin's initialisation function
lt_ptr_t init_func = lt_dlsym(handle, "init");
if (init_func)
((void (*)())init_func)();
lt_ptr_t alloc_func = lt_dlsym(handle, "allocate");
if(alloc_func) {
alloc_ptr = (Client* (*)(Workspace *ws, WId w, int tool))alloc_func;
} else {
qWarning("KWin: The library %s is not a KWin plugin.", path.latin1());
lt_dlclose(handle);
exit(1);
}
pluginStr = nameStr;
emit resetAllClients();
// Call the old plugin's cleanup function
if(oldHandle) {
lt_ptr_t deinit_func = lt_dlsym(oldHandle, "deinit");
if (deinit_func)
@ -203,5 +146,12 @@ void PluginMgr::resetPlugin()
((void (*)())reset_func)();
}
void PluginMgr::shutdownKWin(const QString &error_msg)
{
qWarning( (i18n("KWin: ") + error_msg +
i18n("\nKWin will now exit...")).latin1() );
exit(1);
}
#include "plugins.moc"

View file

@ -27,32 +27,17 @@ public:
void loadPlugin(QString name);
QString currentPlugin() { return pluginStr; }
public slots:
bool updatePlugin();
void updatePlugin();
void resetPlugin();
signals:
void resetAllClients();
protected:
void shutdownKWin(const QString& error_msg);
Client* (*alloc_ptr)(Workspace *ws, WId w, int tool);
lt_dlhandle handle;
QString pluginStr;
};
class PluginMenu : public QPopupMenu
{
Q_OBJECT
public:
PluginMenu(PluginMgr *manager, QWidget *parent=0, const char *name=0);
protected slots:
void slotAboutToShow();
void slotActivated(int id);
protected:
void parseDesktop(QFileInfo *fi);
QStringList fileList;
int idCount;
int idCurrent;
PluginMgr *mgr;
};
};
#endif