From de782ec37b4806823f373d2028586bdbd7716021 Mon Sep 17 00:00:00 2001 From: "Daniel M. Duley" Date: Fri, 24 Dec 1999 01:36:47 +0000 Subject: [PATCH] Implemented plugins :) This was a huge pain in the arse because a) I am stupid and it kept segfaulting because I wasn't releasing windows, and b) The plugins didn't want to resolve anything in the kwin executable, only to the other libs. I finally solved this by using -rdynamic in kwin's LDFLAGS, which I hope is okay ;-) svn path=/trunk/kdebase/kwin/; revision=37234 --- Makefile.am | 6 +- clients/Makefile.am | 1 + clients/be/Makefile.am | 20 ++ clients/be/be.desktop | 3 + clients/be/beclient.cpp | 223 +++++++++++++++++ clients/be/beclient.h | 38 +++ clients/kstep/Makefile.am | 20 ++ clients/kstep/kstep.desktop | 3 + clients/kstep/nextclient.cpp | 299 +++++++++++++++++++++++ clients/kstep/nextclient.h | 48 ++++ clients/system/Makefile.am | 20 ++ clients/system/system.desktop | 3 + clients/system/systemclient.cpp | 408 ++++++++++++++++++++++++++++++++ clients/system/systemclient.h | 52 ++++ plugins.cpp | 177 ++++++++++++++ plugins.h | 45 ++++ workspace.cpp | 97 +++----- workspace.h | 7 +- 18 files changed, 1400 insertions(+), 70 deletions(-) create mode 100644 clients/Makefile.am create mode 100644 clients/be/Makefile.am create mode 100644 clients/be/be.desktop create mode 100644 clients/be/beclient.cpp create mode 100644 clients/be/beclient.h create mode 100644 clients/kstep/Makefile.am create mode 100644 clients/kstep/kstep.desktop create mode 100644 clients/kstep/nextclient.cpp create mode 100644 clients/kstep/nextclient.h create mode 100644 clients/system/Makefile.am create mode 100644 clients/system/system.desktop create mode 100644 clients/system/systemclient.cpp create mode 100644 clients/system/systemclient.h create mode 100644 plugins.cpp create mode 100644 plugins.h diff --git a/Makefile.am b/Makefile.am index daa20fa143..639e24a405 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,12 @@ INCLUDES = $(all_includes) -LDFLAGS = $(all_libraries) $(KDE_RPATH) +LDFLAGS = $(all_libraries) $(KDE_RPATH) -rdynamic -SUBDIRS = pics +SUBDIRS = pics clients bin_PROGRAMS = kwin -kwin_SOURCES = atoms.cpp beclient.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp options.cpp systemclient.cpp nextclient.cpp +kwin_SOURCES = atoms.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp options.cpp plugins.cpp kwin_LDADD = $(LIB_KDECORE) $(LIB_KDEUI) diff --git a/clients/Makefile.am b/clients/Makefile.am new file mode 100644 index 0000000000..a6fc8aeddb --- /dev/null +++ b/clients/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=be kstep system diff --git a/clients/be/Makefile.am b/clients/be/Makefile.am new file mode 100644 index 0000000000..9bfbc091c7 --- /dev/null +++ b/clients/be/Makefile.am @@ -0,0 +1,20 @@ + +INCLUDES = $(all_includes) + +lib_LTLIBRARIES = libkwinbe.la + +libkwinbe_la_SOURCES = beclient.cpp + +METASOURCES = AUTO +noinst_HEADERS = beclient.h + +lnkdir = $(kde_datadir)/kwin/ +lnk_DATA = be.desktop + +EXTRA_DIST = $(lnk_DATA) + +libkwinbe_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -module + +###KMAKE-start (don't edit or delete this block) + +###KMAKE-end diff --git a/clients/be/be.desktop b/clients/be/be.desktop new file mode 100644 index 0000000000..f6fa85340c --- /dev/null +++ b/clients/be/be.desktop @@ -0,0 +1,3 @@ +[Desktop Entry] +Name=Be +X-KDE-Library=libkwinbe diff --git a/clients/be/beclient.cpp b/clients/be/beclient.cpp new file mode 100644 index 0000000000..f11672affd --- /dev/null +++ b/clients/be/beclient.cpp @@ -0,0 +1,223 @@ +#include "beclient.h" +#include +#include +#include +#include +#include +#include +#include +#include "../../workspace.h" + + +extern "C" +{ + Client *allocate(Workspace *ws, WId w) + { + return(new BeClient(ws, w)); + } +} + + +static const char * size_xpm[] = { +/* width height num_colors chars_per_pixel */ +"16 16 3 1", +/* colors */ +" s None c None", +". c #707070", +"X c white", +/* pixels */ +" ", +" ....... ", +" .XXXXXX ", +" .X .X ", +" .X .X....... ", +" .X .XXXXXXXX ", +" .X .X .X ", +" .X....X .X ", +" .XXXXXX .X ", +" .X .X ", +" .X .X ", +" .X .X ", +" .X........X ", +" .XXXXXXXXXX ", +" ", +" "}; + +static QPixmap* size_pix = 0; +static bool pixmaps_created = FALSE; + +static void create_pixmaps() +{ + if ( pixmaps_created ) + return; + pixmaps_created = true; + size_pix = new QPixmap( size_xpm ); +} + +BeClient::BeClient( Workspace *ws, WId w, QWidget *parent, const char *name ) + : Client( ws, w, parent, name, WResizeNoErase ) +{ + create_pixmaps(); + QGridLayout* g = new QGridLayout( this, 0, 0, 2 ); + g->addRowSpacing(1, 2); + g->setRowStretch( 2, 10 ); + g->addWidget( windowWrapper(), 2, 1 ); + g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) ); + g->addColSpacing(0, 2); + g->addColSpacing(2, 2); + g->addRowSpacing(3, 2); + + + + QHBoxLayout* hb = new QHBoxLayout; + g->addLayout( hb, 0, 1 ); + int fh = QMAX( 16, fontMetrics().lineSpacing()); + titlebar = new QSpacerItem(40, fh, QSizePolicy::Preferred, + QSizePolicy::Minimum ); + hb->addItem( titlebar ); + + hb->addStretch(); +} + + +BeClient::~BeClient() +{ +} + + +void BeClient::resizeEvent( QResizeEvent* e) +{ + Client::resizeEvent( e ); + doShape(); + if ( isVisibleToTLW() && !testWFlags( WNorthWestGravity ) ) { + // manual clearing without the titlebar (we selected WResizeNoErase ) + QPainter p( this ); + QRect t = titlebar->geometry(); + t.setTop( 0 ); + t.setLeft( 0 ); + QRegion r = rect(); + r = r.subtract( t ); + p.setClipRegion( r ); + p.eraseRect( rect() ); + } +} + +/*!\reimp + */ +void BeClient::captionChange( const QString& ) +{ + doShape(); + repaint(); +} + +void BeClient::paintEvent( QPaintEvent* ) +{ + QPainter p( this ); + QRect bar ( 0, 0, titlebar->geometry().right()+1, + titlebar->geometry().bottom() ); + qDrawWinPanel( &p, 0, bar.bottom()+2, width(), height() - bar.bottom()-2, + options->colorGroup(Options::Frame, false)); + qDrawWinPanel( &p, 2, bar.bottom()+4, width()-4, height() - bar.bottom()-6, + options->colorGroup(Options::Frame, true)); + + QRect t = titlebar->geometry(); + + bar.setBottom( bar.bottom() + 3 ); + p.setClipRect( bar ); + bar.setBottom( bar.bottom() + 2 ); + qDrawWinPanel( &p, bar, options->colorGroup(Options::TitleBar, isActive()), + FALSE, &options->colorGroup(Options::TitleBar, isActive()). + brush(QColorGroup::Background)); + p.setClipping( FALSE ); + + p.drawPixmap( t.right() - 20, t.center().y()-8, *size_pix ); + p.drawPixmap( t.left() +4, t.center().y()-miniIcon().height()/2, miniIcon() ); + t.setLeft( t.left() + 20 + 5 ); + p.setPen(options->color(Options::Font, isActive())); + p.setFont(options->font(isActive())); + p.drawText( t, AlignLeft|AlignVCenter, caption() ); +} + + +void BeClient::showEvent( QShowEvent* e) +{ + Client::showEvent( e ); + doShape(); + repaint(); +} + +void BeClient::doShape() +{ + QFontMetrics fm = fontMetrics(); + int cap = 20+20+10+10+fm.boundingRect(caption() ).width(); + titlebar->changeSize( QMIN( width(), cap), QMAX( 16, fm.lineSpacing()), + QSizePolicy::Preferred, QSizePolicy::Minimum ); + layout()->activate(); //#### this is broken!!!!! PAUL!!!!! + +// // // do it manually: #######remove this for Qt-2.01 + titlebar->setGeometry( QRect( titlebar->geometry().x(), titlebar->geometry().y(), + titlebar->sizeHint().width(), titlebar->sizeHint().height() ) ); + QRegion r( rect() ); + r = r.subtract( QRect( QPoint( titlebar->geometry().right()+1, 0), QPoint( width(), titlebar->geometry().bottom()) ) ); + setMask( r ); +} + +/*!\reimp + */ +void BeClient::activeChange( bool /* act */ ) +{ + repaint( 0, 0, width(), titlebar->geometry().bottom()+3, FALSE ); +} + +/*!\reimp + */ +Client::MousePosition BeClient::mousePosition( const QPoint& p ) const +{ + const int range = 16; + const int border = 4; + + int ly = titlebar->geometry().bottom(); + int lx = titlebar->geometry().right(); + if ( p.x() > titlebar->geometry().right() ) { + + if ( p.y() <= ly + range && p.x() >= width()-range) + return TopRight; + else if ( p.y() <= ly + border ) + return Top; + } else if ( p.y() < ly ) { + if ( p.y() > border && p.x() < lx - border ) + return Client::mousePosition( p ); + if ( p.y() < range && p.x() > lx - range ) + return TopRight; + else if ( p.x() > lx-border ) + return Right; + } + + return Client::mousePosition( p ); +} + + +void BeClient::mousePressEvent( QMouseEvent * e ) +{ + + Client::mousePressEvent( e ); +} + +void BeClient::mouseReleaseEvent( QMouseEvent * e ) +{ + Client::mouseReleaseEvent( e ); +} + + +void BeClient::mouseDoubleClickEvent( QMouseEvent * e ) +{ + if ( titlebar->geometry().contains( e->pos() ) ) + setShade( !isShade() ); + workspace()->requestFocus( this ); +} + + +void BeClient::windowWrapperShowEvent( QShowEvent* ) +{ + doShape(); +} diff --git a/clients/be/beclient.h b/clients/be/beclient.h new file mode 100644 index 0000000000..cb2a29002a --- /dev/null +++ b/clients/be/beclient.h @@ -0,0 +1,38 @@ +#ifndef BECLIENT_H +#define BECLIENT_H +#include "../../client.h" +class QToolButton; +class QLabel; +class QSpacerItem; + + +class BeClient : public Client +{ + Q_OBJECT +public: + BeClient( Workspace *ws, WId w, QWidget *parent=0, const char *name=0 ); + ~BeClient(); +protected: + void resizeEvent( QResizeEvent* ); + void windowWrapperShowEvent( QShowEvent* ); + void paintEvent( QPaintEvent* ); + void mousePressEvent( QMouseEvent * ); + void mouseReleaseEvent( QMouseEvent * ); + void mouseDoubleClickEvent( QMouseEvent * e ); + + void captionChange( const QString& name ); + + void showEvent( QShowEvent* ); + void activeChange( bool ); + + MousePosition mousePosition( const QPoint& p ) const; + +private: + QSpacerItem* titlebar; + void doShape(); +}; + + + +#endif + diff --git a/clients/kstep/Makefile.am b/clients/kstep/Makefile.am new file mode 100644 index 0000000000..28dfd6ee1b --- /dev/null +++ b/clients/kstep/Makefile.am @@ -0,0 +1,20 @@ + +INCLUDES = $(all_includes) + +lib_LTLIBRARIES = libkwinkstep.la + +libkwinkstep_la_SOURCES = nextclient.cpp + +METASOURCES = AUTO +noinst_HEADERS = nextclient.h + +lnkdir = $(kde_datadir)/kwin/ +lnk_DATA = kstep.desktop + +EXTRA_DIST = $(lnk_DATA) + +libkwinkstep_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -module + +###KMAKE-start (don't edit or delete this block) + +###KMAKE-end diff --git a/clients/kstep/kstep.desktop b/clients/kstep/kstep.desktop new file mode 100644 index 0000000000..e174f39534 --- /dev/null +++ b/clients/kstep/kstep.desktop @@ -0,0 +1,3 @@ +[Desktop Entry] +Name=KStep +X-KDE-Library=libkwinkstep diff --git a/clients/kstep/nextclient.cpp b/clients/kstep/nextclient.cpp new file mode 100644 index 0000000000..3b5f12a70a --- /dev/null +++ b/clients/kstep/nextclient.cpp @@ -0,0 +1,299 @@ +#include "nextclient.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../workspace.h" +#include "../../options.h" + +extern "C" +{ + Client *allocate(Workspace *ws, WId w) + { + return(new NextClient(ws, w)); + } +} + + +static unsigned char close_bits[] = { + 0x03, 0x03, 0x87, 0x03, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x78, 0x00, + 0xfc, 0x00, 0xce, 0x01, 0x87, 0x03, 0x03, 0x03}; + +static unsigned char iconify_bits[] = { + 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0xff, 0x03, 0xff, 0x03}; + +static unsigned char sticky_bits[] = { + 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00}; + +static unsigned char unsticky_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static KPixmap *aTitlePix=0; +static KPixmap *iTitlePix=0; +static KPixmap *aFramePix=0; +static KPixmap *iFramePix=0; +static KPixmap *aHandlePix=0; +static KPixmap *iHandlePix=0; +static bool pixmaps_created = false; + +static void create_pixmaps() +{ + if(pixmaps_created) + return; + pixmaps_created = true; + + aTitlePix = new KPixmap(); + aTitlePix->resize(32, 14); + KPixmapEffect::gradient(*aTitlePix, + options->color(Options::TitleBar, true), + options->color(Options::TitleBlend, true), + KPixmapEffect::VerticalGradient); + iTitlePix = new KPixmap(); + iTitlePix->resize(32, 14); + KPixmapEffect::gradient(*iTitlePix, + options->color(Options::TitleBar, false), + options->color(Options::TitleBlend, false), + KPixmapEffect::VerticalGradient); + // Bottom frame gradient + aFramePix = new KPixmap(); + aFramePix->resize(32, 6); + KPixmapEffect::gradient(*aFramePix, + options->color(Options::Frame, true).light(150), + options->color(Options::Frame, true).dark(120), + KPixmapEffect::VerticalGradient); + iFramePix = new KPixmap(); + iFramePix->resize(32, 6); + KPixmapEffect::gradient(*iFramePix, + options->color(Options::Frame, false).light(150), + options->color(Options::Frame, false).dark(120), + KPixmapEffect::VerticalGradient); + + // Handle gradient + aHandlePix = new KPixmap(); + aHandlePix->resize(32, 6); + KPixmapEffect::gradient(*aHandlePix, + options->color(Options::Handle, true).light(150), + options->color(Options::Handle, true).dark(120), + KPixmapEffect::VerticalGradient); + iHandlePix = new KPixmap(); + iHandlePix->resize(32, 6); + KPixmapEffect::gradient(*iHandlePix, + options->color(Options::Handle, false).light(150), + options->color(Options::Handle, false).dark(120), + KPixmapEffect::VerticalGradient); + +} + +NextButton::NextButton(QWidget *parent, const char *name, + const unsigned char *bitmap, int bw, int bh) + : QButton(parent, name) +{ + QPainter p; + + aBackground.resize(18, 18); + iBackground.resize(18, 18); + + QColor hColor(options->color(Options::ButtonBg, true)); + QColor lColor(options->color(Options::ButtonBlend, true)); + // only do this if we can dim/brighten equally + if(hColor.red() < 226 && hColor.green() < 226 && hColor.blue() < 226) + hColor.setRgb(hColor.red()+30, hColor.green()+30, hColor.blue()+30); + if(lColor.red() > 29 && lColor.green() > 29 && lColor.blue() > 29) + lColor.setRgb(lColor.red()-30, lColor.green()-30, lColor.blue()-30); + KPixmapEffect::gradient(iBackground, hColor, lColor, + KPixmapEffect::DiagonalGradient); + + hColor = options->color(Options::ButtonBlend, false); + lColor = options->color(Options::ButtonBg, false); + if(hColor.red() > 29 && hColor.green() > 29 && hColor.blue() > 29) + hColor.setRgb(hColor.red()-30, hColor.green()-30, hColor.blue()-30); + if(lColor.red() < 226 && lColor.green() < 226 && lColor.blue() < 226) + lColor.setRgb(lColor.red()+30, lColor.green()+30, lColor.blue()+30); + KPixmapEffect::gradient(aBackground, hColor, lColor, + KPixmapEffect::DiagonalGradient); + + KPixmap aInternal; + aInternal.resize(12, 12); + KPixmap iInternal; + iInternal.resize(12, 12); + KPixmapEffect::gradient(iInternal, + options->color(Options::ButtonBlend, true), + options->color(Options::ButtonBg, true), + KPixmapEffect::DiagonalGradient); + KPixmapEffect::gradient(aInternal, + options->color(Options::ButtonBg, false), + options->color(Options::ButtonBlend, false), + KPixmapEffect::DiagonalGradient); + + p.begin(&iBackground); + p.drawPixmap(3, 3, iInternal); + p.setPen(Qt::black); + p.drawRect(0, 0, 18, 18); + p.end(); + + p.begin(&aBackground); + p.drawPixmap(3, 3, aInternal); + p.setPen(Qt::black); + p.drawRect(0, 0, 18, 18); + p.end(); + + resize(18, 18); + + if(bitmap) + setBitmap(bitmap, bw, bh); +} + +void NextButton::setBitmap(const unsigned char *bitmap, int w, int h) +{ + deco = QBitmap(w, h, bitmap, true); + deco.setMask(deco); + repaint(); +} + +void NextButton::drawButton(QPainter *p) +{ + if(isDown()) + p->drawPixmap(0, 0, aBackground); + else + p->drawPixmap(0, 0, iBackground); + + p->setPen(options->color(Options::ButtonFg, isDown())); + p->drawPixmap(isDown()? 5 : 4, isDown() ? 5 : 4, deco); +} + +NextClient::NextClient( Workspace *ws, WId w, QWidget *parent, + const char *name ) + : Client( ws, w, parent, name, WResizeNoErase ) +{ + create_pixmaps(); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + QHBoxLayout *titleLayout = new QHBoxLayout(); + QHBoxLayout *windowLayout = new QHBoxLayout(); + + mainLayout->addLayout(titleLayout); + mainLayout->addLayout(windowLayout, 1); + mainLayout->addSpacing(6); + + windowLayout->addSpacing(1); + windowLayout->addWidget(windowWrapper(), 1); + windowLayout->addSpacing(1); + + + button[0] = new NextButton(this, "close", close_bits, 10, 10); + button[1] = new NextButton(this, "sticky"); + if(isSticky()) + button[1]->setBitmap(unsticky_bits, 10, 10); + else + button[1]->setBitmap(sticky_bits, 10, 10); + button[2] = new NextButton(this, "iconify", iconify_bits, 10, 10); + + connect( button[0], SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) ); + connect( button[1], SIGNAL( clicked() ), this, ( SLOT( toggleSticky() ) ) ); + connect( button[2], SIGNAL( clicked() ), this, ( SLOT( iconify() ) ) ); + titleLayout->addWidget( button[2] ); + titlebar = new QSpacerItem(10, 16, QSizePolicy::Expanding, + QSizePolicy::Minimum ); + titleLayout->addItem(titlebar); + titleLayout->addWidget( button[1] ); + titleLayout->addWidget( button[0] ); + for ( int i = 0; i < 3; i++) { + button[i]->setMouseTracking( TRUE ); + button[i]->setFixedSize( 18, 18 ); + } + +} + +void NextClient::resizeEvent( QResizeEvent* e) +{ + Client::resizeEvent( e ); + + if ( isVisibleToTLW() && !testWFlags( WNorthWestGravity )) { + QPainter p( this ); + QRect t = titlebar->geometry(); + t.setTop( 0 ); + QRegion r = rect(); + r = r.subtract( t ); + p.setClipRegion( r ); + p.eraseRect( rect() ); + } +} + +void NextClient::captionChange( const QString& ) +{ + repaint( titlebar->geometry(), false ); +} + + +void NextClient::paintEvent( QPaintEvent* ) +{ + QPainter p( this ); + p.setPen(Qt::black); + p.drawRect(rect()); + + QRect t = titlebar->geometry(); + t.setTop(1); + p.drawTiledPixmap(t.x()+1, t.y()+1, t.width()-2, t.height()-2, + isActive() ? *aTitlePix : *iTitlePix); + qDrawShadePanel(&p, t.x(), t.y(), t.width(), t.height()-1, + options->colorGroup(Options::TitleBar, isActive())); + p.drawLine(t.x(), t.bottom(), t.right(), t.bottom()); + QRegion r = rect(); + r = r.subtract( t ); + p.setClipRegion( r ); + p.setClipping( FALSE ); + + t.setTop( 2 ); + t.setHeight(t.height()-4); + t.setLeft( t.left() + 4 ); + t.setRight( t.right() - 2 ); + + p.setPen(options->color(Options::Font, isActive())); + p.setFont(options->font(isActive())); + p.drawText( t, AlignCenter, caption() ); + + + qDrawShadePanel(&p, rect().x()+1, rect().bottom()-6, 24, 6, + options->colorGroup(Options::Handle, isActive()), false); + p.drawTiledPixmap(rect().x()+2, rect().bottom()-5, 22, 4, + isActive() ? *aHandlePix : *iHandlePix); + + qDrawShadePanel(&p, rect().x()+25, rect().bottom()-6, rect().width()-50, 6, + options->colorGroup(Options::Frame, isActive()), false); + p.drawTiledPixmap(rect().x()+26, rect().bottom()-5, rect().width()-52, 4, + isActive() ? *aFramePix : *iFramePix); + + qDrawShadePanel(&p, rect().right()-24, rect().bottom()-6, 24, 6, + options->colorGroup(Options::Handle, isActive()), false); + p.drawTiledPixmap(rect().right()-23, rect().bottom()-5, 22, 4, + isActive() ? *aHandlePix : *iHandlePix); +} + +void NextClient::mouseDoubleClickEvent( QMouseEvent * e ) +{ + if (titlebar->geometry().contains( e->pos() ) ) + setShade( !isShade() ); + workspace()->requestFocus( this ); +} + +void NextClient::stickyChange(bool on) +{ + if(on) + button[1]->setBitmap(unsticky_bits, 8, 8); + else + button[1]->setBitmap(sticky_bits, 8, 8); +} + + +void NextClient::init() +{ + Client::init(); +} + diff --git a/clients/kstep/nextclient.h b/clients/kstep/nextclient.h new file mode 100644 index 0000000000..b6709be142 --- /dev/null +++ b/clients/kstep/nextclient.h @@ -0,0 +1,48 @@ +#ifndef __NEXTCLIENT_H +#define __NEXTCLIENT_H + +#include +#include +#include +#include "../../client.h" +class QLabel; +class QSpacerItem; + + +// get rid of autohide :P +class NextButton : public QButton +{ +public: + NextButton(QWidget *parent=0, const char *name=0, + const unsigned char *bitmap=NULL, int bw=0, int bh=0); + void setBitmap(const unsigned char *bitmap, int bw, int bh); +protected: + virtual void drawButton(QPainter *p); + void drawButtonLabel(QPainter *){;} + KPixmap aBackground, iBackground; + QBitmap deco; +}; + +class NextClient : public Client +{ + Q_OBJECT +public: + NextClient( Workspace *ws, WId w, QWidget *parent=0, const char *name=0 ); + ~NextClient(){;} +protected: + void resizeEvent( QResizeEvent* ); + void paintEvent( QPaintEvent* ); + + void mouseDoubleClickEvent( QMouseEvent * ); + void init(); + void captionChange( const QString& name ); + void stickyChange(bool on); +private: + NextButton* button[3]; + QSpacerItem* titlebar; +}; + + + + +#endif diff --git a/clients/system/Makefile.am b/clients/system/Makefile.am new file mode 100644 index 0000000000..3f45d4c724 --- /dev/null +++ b/clients/system/Makefile.am @@ -0,0 +1,20 @@ + +INCLUDES = $(all_includes) + +lib_LTLIBRARIES = libkwinsystem.la + +libkwinsystem_la_SOURCES = systemclient.cpp + +METASOURCES = AUTO +noinst_HEADERS = systemclient.h + +lnkdir = $(kde_datadir)/kwin/ +lnk_DATA = system.desktop + +EXTRA_DIST = $(lnk_DATA) + +libkwinsystem_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -module + +###KMAKE-start (don't edit or delete this block) + +###KMAKE-end diff --git a/clients/system/system.desktop b/clients/system/system.desktop new file mode 100644 index 0000000000..b264fbb200 --- /dev/null +++ b/clients/system/system.desktop @@ -0,0 +1,3 @@ +[Desktop Entry] +Name=System +X-KDE-Library=libkwinsystem diff --git a/clients/system/systemclient.cpp b/clients/system/systemclient.cpp new file mode 100644 index 0000000000..129eae014d --- /dev/null +++ b/clients/system/systemclient.cpp @@ -0,0 +1,408 @@ +#include "systemclient.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../workspace.h" +#include "../../options.h" + +extern "C" +{ + Client *allocate(Workspace *ws, WId w) + { + return(new SystemClient(ws, w)); + } +} + + +static unsigned char iconify_bits[] = { + 0xff, 0xff, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18}; + +static unsigned char close_bits[] = { + 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00 }; + +static unsigned char maximize_bits[] = { + 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0xff, 0xff }; + +static unsigned char minmax_bits[] = { + 0x0c, 0x18, 0x33, 0x67, 0xcf, 0x9f, 0x3f, 0x3f}; + +static unsigned char unsticky_bits[] = { + 0x00, 0x18, 0x18, 0x7e, 0x7e, 0x18, 0x18, 0x00}; + +static unsigned char sticky_bits[] = { + 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x00}; + +static unsigned char question_bits[] = { + 0x3c, 0x66, 0x60, 0x30, 0x18, 0x00, 0x18, 0x18}; + +static QPixmap *titlePix=0; +static KPixmap *aFramePix=0; +static KPixmap *iFramePix=0; +static KPixmap *aHandlePix=0; +static KPixmap *iHandlePix=0; +static bool pixmaps_created = false; + +static void create_pixmaps() +{ + if(pixmaps_created) + return; + pixmaps_created = true; + + // titlebar + QPainter p; + QPainter maskPainter; + int i, y; + titlePix = new QPixmap(32, 14); + QBitmap mask(32, 14); + mask.fill(Qt::color0); + + p.begin(titlePix); + maskPainter.begin(&mask); + maskPainter.setPen(Qt::color1); + for(i=0, y=2; i < 4; ++i, y+=3){ + p.setPen(options->color(Options::TitleBar, true).light(150)); + p.drawLine(0, y, 31, y); + maskPainter.drawLine(0, y, 31, y); + p.setPen(options->color(Options::TitleBar, true).dark(120)); + p.drawLine(0, y+1, 31, y+1); + maskPainter.drawLine(0, y+1, 31, y+1); + } + p.end(); + maskPainter.end(); + titlePix->setMask(mask); + + // Bottom frame gradient + aFramePix = new KPixmap(); + aFramePix->resize(32, 6); + KPixmapEffect::gradient(*aFramePix, + options->color(Options::Frame, true).light(150), + options->color(Options::Frame, true).dark(120), + KPixmapEffect::VerticalGradient); + iFramePix = new KPixmap(); + iFramePix->resize(32, 6); + KPixmapEffect::gradient(*iFramePix, + options->color(Options::Frame, false).light(150), + options->color(Options::Frame, false).dark(120), + KPixmapEffect::VerticalGradient); + + // Handle gradient + aHandlePix = new KPixmap(); + aHandlePix->resize(32, 6); + KPixmapEffect::gradient(*aHandlePix, + options->color(Options::Handle, true).light(150), + options->color(Options::Handle, true).dark(120), + KPixmapEffect::VerticalGradient); + iHandlePix = new KPixmap(); + iHandlePix->resize(32, 6); + KPixmapEffect::gradient(*iHandlePix, + options->color(Options::Handle, false).light(150), + options->color(Options::Handle, false).dark(120), + KPixmapEffect::VerticalGradient); + +} + + +SystemButton::SystemButton(QWidget *parent, const char *name, + const unsigned char *bitmap) + : QButton(parent, name) +{ + QPainter p; + + aBackground.resize(14, 14); + iBackground.resize(14, 14); + + QColor hColor(options->color(Options::ButtonBg, true)); + QColor lColor(options->color(Options::ButtonBlend, true)); + // only do this if we can dim/brighten equally + if(hColor.red() < 226 && hColor.green() < 226 && hColor.blue() < 226) + hColor.setRgb(hColor.red()+30, hColor.green()+30, hColor.blue()+30); + if(lColor.red() > 29 && lColor.green() > 29 && lColor.blue() > 29) + lColor.setRgb(lColor.red()-30, lColor.green()-30, lColor.blue()-30); + KPixmapEffect::gradient(iBackground, hColor, lColor, + KPixmapEffect::DiagonalGradient); + + hColor = options->color(Options::ButtonBlend, false); + lColor = options->color(Options::ButtonBg, false); + if(hColor.red() > 29 && hColor.green() > 29 && hColor.blue() > 29) + hColor.setRgb(hColor.red()-30, hColor.green()-30, hColor.blue()-30); + if(lColor.red() < 226 && lColor.green() < 226 && lColor.blue() < 226) + lColor.setRgb(lColor.red()+30, lColor.green()+30, lColor.blue()+30); + KPixmapEffect::gradient(aBackground, hColor, lColor, + KPixmapEffect::DiagonalGradient); + + KPixmap aInternal; + aInternal.resize(10, 10); + KPixmap iInternal; + iInternal.resize(10, 10); + KPixmapEffect::gradient(iInternal, + options->color(Options::ButtonBlend, true), + options->color(Options::ButtonBg, true), + KPixmapEffect::DiagonalGradient); + KPixmapEffect::gradient(aInternal, + options->color(Options::ButtonBg, false), + options->color(Options::ButtonBlend, false), + KPixmapEffect::DiagonalGradient); + + p.begin(&iBackground); + p.drawPixmap(2, 2, iInternal); + p.setPen(options->color(Options::ButtonBg, false)); + p.drawLine(0, 13, 13, 13); + p.drawLine(13, 0, 13, 13); + p.setPen(options->color(Options::ButtonBlend, false)); + p.drawLine(0, 0, 12, 0); + p.drawLine(0, 0, 0, 12); + p.end(); + + p.begin(&aBackground); + p.drawPixmap(2, 2, aInternal); + p.setPen(options->color(Options::ButtonFg, true)); + p.drawRect(0, 0, 14, 14); + + p.end(); + + resize(14, 14); + + if(bitmap) + setBitmap(bitmap); +} + +void SystemButton::setBitmap(const unsigned char *bitmap) +{ + deco = QBitmap(8, 8, bitmap, true); + deco.setMask(deco); + repaint(); +} + +void SystemButton::drawButton(QPainter *p) +{ + if(isDown()) + p->drawPixmap(0, 0, aBackground); + else + p->drawPixmap(0, 0, iBackground); + + p->setPen(options->color(Options::ButtonFg, isDown())); + p->drawPixmap(isDown() ? 4 : 3, isDown() ? 4 : 3, deco); +} + +SystemClient::SystemClient( Workspace *ws, WId w, QWidget *parent, + const char *name ) + : Client( ws, w, parent, name, WResizeNoErase ) +{ + create_pixmaps(); + bool help = providesContextHelp(); + + QGridLayout* g = new QGridLayout(this, 0, 0, 2); + g->setRowStretch(1, 10); + g->addWidget(windowWrapper(), 1, 1 ); + g->addItem( new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) ); + + g->addColSpacing(0, 2); + g->addColSpacing(2, 2); + g->addRowSpacing(2, 6); + + button[0] = new SystemButton(this, "close", close_bits); + button[1] = new SystemButton(this, "sticky"); + if(isSticky()) + button[1]->setBitmap(unsticky_bits); + else + button[1]->setBitmap(sticky_bits); + button[2] = new SystemButton(this, "iconify", iconify_bits); + button[3] = new SystemButton(this, "maximize", maximize_bits); + if(help){ + button[4] = new SystemButton(this, "help", question_bits); + connect( button[4], SIGNAL( clicked() ), this, ( SLOT( contextHelp() ) ) ); + } + + connect( button[0], SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) ); + connect( button[1], SIGNAL( clicked() ), this, ( SLOT( toggleSticky() ) ) ); + connect( button[2], SIGNAL( clicked() ), this, ( SLOT( iconify() ) ) ); + connect( button[3], SIGNAL( clicked() ), this, ( SLOT( maximize() ) ) ); + + QHBoxLayout* hb = new QHBoxLayout(); + g->addLayout( hb, 0, 1 ); + hb->addSpacing(2); + hb->addWidget( button[0] ); + titlebar = new QSpacerItem(10, 16, QSizePolicy::Expanding, + QSizePolicy::Minimum); + hb->addItem(titlebar); + hb->addSpacing(3); + if(help){ + hb->addWidget( button[4] ); + hb->addSpacing(1); + } + hb->addWidget( button[1] ); + hb->addSpacing(1); + hb->addWidget( button[2] ); + hb->addSpacing(1); + hb->addWidget( button[3] ); + hb->addSpacing(3); + + for ( int i = 0; i < (help ? 5 : 4); i++) { + button[i]->setMouseTracking( TRUE ); + button[i]->setFixedSize( 14, 14 ); + } +} + +void SystemClient::resizeEvent( QResizeEvent* e) +{ + Client::resizeEvent( e ); + doShape(); + if ( isVisibleToTLW() && !testWFlags( WNorthWestGravity )) { + QPainter p( this ); + QRect t = titlebar->geometry(); + t.setTop( 0 ); + QRegion r = rect(); + r = r.subtract( t ); + p.setClipRegion( r ); + p.eraseRect( rect() ); + } +} + +void SystemClient::captionChange( const QString& ) +{ + repaint( titlebar->geometry(), false ); +} + +void SystemClient::drawRoundFrame(QPainter &p, int x, int y, int w, int h) +{ + int x2=x+w-1, y2=y+h-1; + QPointArray hPntArray, lPntArray; + hPntArray.putPoints(0, 12, x+4,y+1, x+5,y+1, // top left + x+3,y+2, x+2,y+3, x+1,y+4, x+1,y+5, + x+1,y2-5, x+1,y2-4, x+2,y2-3, // half corners + x2-5,y+1, x2-4,y+1, x2-3,y+2); + + lPntArray.putPoints(0, 17, x2-5,y2-1, x2-4,y2-1, // btm right + x2-3,y2-2, x2-2,y2-3, x2-1,y2-5, x2-1,y2-4, + + x+3,y2-2, x+4,y2-1, x+5,y2-1, //half corners + x2-2,y+3, x2-1,y+4, x2-1,y+5, + + x2-5,y2-2, x2-4,y2-2, // testing + x2-3,y2-3, + x2-2,y2-5, x2-2,y2-4); + + p.setPen(options->colorGroup(Options::Frame, isActive()).light()); + p.drawLine(x+6, y, x2-6, y); + p.drawLine(0, y+6, 0, y2-6); + p.drawPoints(hPntArray); + p.setPen(options->colorGroup(Options::Frame, isActive()).dark()); + p.drawLine(x+6, y2, x2-6, y2); + p.drawLine(x+6, y2-1, x2-6, y2-1); + p.drawLine(x2, y+6, x2, y2-6); + p.drawLine(x2-1, y+6, x2-1, y2-6); + p.drawPoints(lPntArray); +} + +void SystemClient::paintEvent( QPaintEvent* ) +{ + QPainter p( this ); + QRect t = titlebar->geometry(); + t.setTop( 1 ); + + QBrush fillBrush(colorGroup().brush(QColorGroup::Background).pixmap() ? + colorGroup().brush(QColorGroup::Background) : + options->colorGroup(Options::Frame, isActive()). + brush(QColorGroup::Button)); + + p.fillRect(rect(), fillBrush); + drawRoundFrame(p, 0, 0, width(), height()); + t.setTop( 2 ); + if(isActive()) + p.drawTiledPixmap(t, *titlePix); + + QRegion r = rect(); + r = r.subtract( t ); + p.setClipRegion( r ); + p.setClipping( FALSE ); + + t.setTop( 2 ); + t.setLeft( t.left() + 4 ); + t.setRight( t.right() - 2 ); + + p.setPen(options->color(Options::Font, isActive())); + p.setFont(options->font(isActive())); + if(isActive()){ + QFontMetrics fm(options->font(true)); + p.fillRect(t.x()+((t.width()-fm.width(caption()))/2)-4, t.y(), + fm.width(caption())+8, t.height(), fillBrush); + } + + p.drawText( t, AlignCenter, caption() ); + + p.setPen(options->colorGroup(Options::Frame, isActive()).light()); + p.drawLine(width()-20, height()-7, width()-10, height()-7); + p.drawLine(width()-20, height()-5, width()-10, height()-5); + p.setPen(options->colorGroup(Options::Frame, isActive()).dark()); + p.drawLine(width()-20, height()-6, width()-10, height()-6); + p.drawLine(width()-20, height()-4, width()-10, height()-4); +} + +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + +void SystemClient::doShape() +{ + // using a bunch of QRect lines seems much more efficent than bitmaps or + // point arrays + + QRegion mask(QRect(6, 0, width()-12, height())); + mask += QRegion(QRect(5, 1, 1, height()-2)); // left + mask += QRegion(QRect(4, 1, 1, height()-2)); + mask += QRegion(QRect(3, 2, 1, height()-4)); + mask += QRegion(QRect(2, 3, 1, height()-6)); + mask += QRegion(QRect(1, 4, 1, height()-8)); + mask += QRegion(QRect(0, 6, 1, height()-12)); + int x2 = width()-1; + mask += QRegion(QRect(x2-5, 1, 1, height()-2)); // right + mask += QRegion(QRect(x2-4, 1, 1, height()-2)); + mask += QRegion(QRect(x2-3, 2, 1, height()-4)); + mask += QRegion(QRect(x2-2, 3, 1, height()-6)); + mask += QRegion(QRect(x2-1, 4, 1, height()-8)); + mask += QRegion(QRect(x2, 6, 1, height()-12)); + + setMask(mask); + + +} + +void SystemClient::showEvent(QShowEvent *ev) +{ + Client::showEvent(ev); + doShape(); + repaint(); +} + +void SystemClient::windowWrapperShowEvent( QShowEvent* ) +{ + doShape(); +} + +void SystemClient::mouseDoubleClickEvent( QMouseEvent * e ) +{ + if (titlebar->geometry().contains( e->pos() ) ) + setShade( !isShade() ); + workspace()->requestFocus( this ); +} + +void SystemClient::stickyChange(bool on) +{ + button[1]->setBitmap(on ? unsticky_bits : sticky_bits); +} + +void SystemClient::maximizeChange(bool m) +{ + button[3]->setBitmap(m ? minmax_bits : maximize_bits); +} + +void SystemClient::init() +{ + // +} + + diff --git a/clients/system/systemclient.h b/clients/system/systemclient.h new file mode 100644 index 0000000000..67c5b50d70 --- /dev/null +++ b/clients/system/systemclient.h @@ -0,0 +1,52 @@ +#ifndef __SYSTEMCLIENT_H +#define __SYSTEMCLIENT_H + +#include +#include +#include +#include "../../client.h" +class QLabel; +class QSpacerItem; + + +// get rid of autohide :P +class SystemButton : public QButton +{ +public: + SystemButton(QWidget *parent=0, const char *name=0, + const unsigned char *bitmap=NULL); + void setBitmap(const unsigned char *bitmap); +protected: + virtual void drawButton(QPainter *p); + void drawButtonLabel(QPainter *){;} + KPixmap aBackground, iBackground; + QBitmap deco; +}; + +class SystemClient : public Client +{ + Q_OBJECT +public: + SystemClient( Workspace *ws, WId w, QWidget *parent=0, const char *name=0 ); + ~SystemClient(){;} +protected: + void drawRoundFrame(QPainter &p, int x, int y, int w, int h); + void resizeEvent( QResizeEvent* ); + void paintEvent( QPaintEvent* ); + void showEvent( QShowEvent* ); + void windowWrapperShowEvent( QShowEvent* ); + void mouseDoubleClickEvent( QMouseEvent * ); + void init(); + void captionChange( const QString& name ); + void stickyChange(bool on); + void maximizeChange(bool m); + void doShape(); +private: + SystemButton* button[5]; + QSpacerItem* titlebar; +}; + + + + +#endif diff --git a/plugins.cpp b/plugins.cpp new file mode 100644 index 0000000000..67a1a2b729 --- /dev/null +++ b/plugins.cpp @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "plugins.h" +#include "stdclient.h" + +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; +} + +void PluginMenu::slotAboutToShow() +{ + clear(); + fileList.clear(); + insertItem(i18n("Standard"), 0); + idCount = 1; + + 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); + } + } + } + } + } +} + +void PluginMenu::parseDesktop(QFileInfo *fi) +{ + QString tmpStr; + KSimpleConfig config(fi->absFilePath(), true); + config.setDesktopGroup(); + tmpStr = config.readEntry("X-KDE-Library", ""); + if(tmpStr.isEmpty()){ + warning("KWin: Invalid plugin: %s", fi->absFilePath().latin1()); + return; + } + fileList.append(tmpStr); + tmpStr = config.readEntry("Name", ""); + if(tmpStr.isEmpty()) + tmpStr = fi->baseName(); + insertItem(tmpStr, idCount); + ++idCount; +} + +void PluginMenu::slotActivated(int id) +{ + if(id == 0) + mgr->loadPlugin(QString::null); + else + mgr->loadPlugin(fileList[id-1]); +} + +PluginMgr::PluginMgr() + : QObject() +{ + alloc_ptr = NULL; + handle = 0; + + QString pluginStr; + KConfig *config = KGlobal::config(); + config->setGroup("Style"); + pluginStr = config->readEntry("PluginLib", "standard"); + if(pluginStr.isEmpty() || pluginStr == "standard") + return; + else + loadPlugin(pluginStr); +} + +PluginMgr::~PluginMgr() +{ + if(handle) + lt_dlclose(handle); +} + +Client* PluginMgr::allocateClient(Workspace *ws, WId w) +{ + if(alloc_ptr) + return(alloc_ptr(ws, w)); + else + return(new StdClient(ws, w)); +} + +void PluginMgr::loadPlugin(QString nameStr) +{ + static bool dlregistered = false; + static lt_dlhandle oldHandle = 0; + + KConfig *config = KGlobal::config(); + config->setGroup("Style"); + config->writeEntry("PluginLib", nameStr); + oldHandle = handle; + + if(nameStr.isNull()){ + handle = 0; + alloc_ptr = NULL; + config->writeEntry("PluginLib", "standard"); + } + else{ + if(!dlregistered){ + dlregistered = true; + lt_dlinit(); + } + nameStr += ".la"; + nameStr = KGlobal::dirs()->findResource("lib", nameStr); + + if(!nameStr){ + warning("KWin: cannot find client plugin."); + handle = 0; + alloc_ptr = NULL; + config->writeEntry("PluginLib", "standard"); + } + else{ + handle = lt_dlopen(nameStr.latin1()); + if(!handle){ + warning("KWin: cannot load client plugin %s.", nameStr.latin1()); + handle = 0; + alloc_ptr = NULL; + config->writeEntry("PluginLib", "standard"); + } + else{ + lt_ptr_t alloc_func = lt_dlsym(handle, "allocate"); + if(alloc_func) + alloc_ptr = (Client* (*)(Workspace *ws, WId w))alloc_func; + else{ + warning("KWin: %s is not a KWin plugin.", nameStr.latin1()); + lt_dlclose(handle); + handle = 0; + alloc_ptr = NULL; + config->writeEntry("PluginLib", "standard"); + } + } + } + } + config->sync(); + emit resetAllClients(); + if(oldHandle) + lt_dlclose(oldHandle); +} + + + diff --git a/plugins.h b/plugins.h new file mode 100644 index 0000000000..d920beee7c --- /dev/null +++ b/plugins.h @@ -0,0 +1,45 @@ +#ifndef __PLUGINS_H +#define __PLUGINS_H + +#include +#include +#include + + +class Client; +class Workspace; + +class QFileInfo; + +class PluginMgr : public QObject +{ + Q_OBJECT +public: + PluginMgr(); + ~PluginMgr(); + Client *allocateClient(Workspace *ws, WId w); + void loadPlugin(QString name); +signals: + void resetAllClients(); +protected: + Client* (*alloc_ptr)(Workspace *ws, WId w); + lt_dlhandle handle; +}; + +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; + PluginMgr *mgr; +}; + + +#endif diff --git a/workspace.cpp b/workspace.cpp index 6cd55353c6..6edae7ccd1 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -9,11 +9,9 @@ #include "workspace.h" #include "client.h" #include "stdclient.h" -#include "beclient.h" -#include "systemclient.h" -#include "nextclient.h" #include "tabbox.h" #include "atoms.h" +#include "plugins.h" #include #include #include @@ -50,7 +48,7 @@ int Shape::shapeEvent() } -static Client* clientFactory( Workspace *ws, WId w ) +Client* Workspace::clientFactory( Workspace *ws, WId w ) { // hack TODO hints char* name = 0; @@ -79,19 +77,7 @@ static Client* clientFactory( Workspace *ws, WId w ) if ( Shape::hasShape( w ) ){ return new NoBorderClient( ws, w ); } - - KConfig *config = KGlobal::config(); - config->setGroup("Style"); - // well, it will be soon ;-) - QString tmpStr = config->readEntry("Plugin", "standard"); - if(tmpStr == "system") - return new SystemClient( ws, w ); - else if(tmpStr == "next") - return new NextClient( ws, w ); - else if(tmpStr == "Be") - return new BeClient( ws, w ); - else - return new StdClient( ws, w ); + return(mgr.allocateClient(ws, w)); } Workspace::Workspace() @@ -177,6 +163,9 @@ void Workspace::init() Window dw1, dw2, *wins; XWindowAttributes attr; + connect(&mgr, SIGNAL(resetAllClients()), this, + SLOT(slotResetAllClients())); + XGrabServer( qt_xdisplay() ); XQueryTree(qt_xdisplay(), root, &dw1, &dw2, &wins, &nwins); for (i = 0; i < nwins; i++) { @@ -908,15 +897,8 @@ QPopupMenu* Workspace::clientPopup( Client* c ) connect( popup, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) ); connect( popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) ); - - QPopupMenu* deco = new QPopupMenu( popup ); - connect( deco, SIGNAL( activated(int) ), this, SLOT( setDecorationStyle(int) ) ); - deco->insertItem( i18n( "KDE Classic" ), 1 ); - deco->insertItem( i18n( "Be-like style" ), 2); - deco->insertItem( i18n( "System style" ), 3 ); - deco->insertItem( i18n( "Next-like style" ), 4 ); + PluginMenu *deco = new PluginMenu(&mgr, popup); - desk_popup = new QPopupMenu( popup ); desk_popup->setCheckable( TRUE ); connect( desk_popup, SIGNAL( activated(int) ), this, SLOT( sendToDesktop(int) ) ); @@ -1436,47 +1418,6 @@ void Workspace::setCurrentDesktop( int new_desktop ){ -// experimental -void Workspace::setDecorationStyle( int deco ) -{ - if ( !popup_client ) - return; - Client* c = popup_client; - WId w = c->window(); - clients.remove( c ); - stacking_order.remove( c ); - focus_chain.remove( c ); - bool mapped = c->isVisible(); - c->hide(); - c->releaseWindow(); - KWM::moveToDesktop( w, c->desktop() ); - KConfig* config = KGlobal::config(); - config->setGroup("Style"); - switch ( deco ) { - case 2: - c = new BeClient( this, w); - config->writeEntry("Plugin", "Be"); - break; - case 3: - c = new SystemClient(this, w); - config->writeEntry("Plugin", "system"); - break; - case 4: - c = new NextClient(this, w); - config->writeEntry("Plugin", "next"); - break; - default: - c = new StdClient( this, w ); - config->writeEntry("Plugin", "standard"); - } - config->sync(); - clients.append( c ); - stacking_order.append( c ); - c->manage( mapped ); - activateClient( c ); -} - - QWidget* Workspace::desktopWidget() { return desktop_widget; @@ -2030,3 +1971,27 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent key ) } + +void Workspace::slotResetAllClients() +{ + for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) { + Client *oldClient = (*it); + + WId w = oldClient->window(); + bool mapped = oldClient->isVisible(); + oldClient->hide(); + oldClient->releaseWindow(); + // Replace oldClient with newClient in all lists + Client *newClient = clientFactory (this, w); + (*it) = newClient; + ClientList::Iterator jt = stacking_order.find (oldClient); + //assert (jt != stacking_order.end()); + (*jt) = newClient; + jt = focus_chain.find (oldClient); + //assert (jt != focus_chain.end()); + (*jt) = newClient; + // Delete the old, display the new + delete oldClient; + newClient->manage (mapped); + } +} diff --git a/workspace.h b/workspace.h index dc3beb5159..4916bf0cde 100644 --- a/workspace.h +++ b/workspace.h @@ -8,6 +8,7 @@ #include #include #include "options.h" +#include "plugins.h" class Client; class TabBox; @@ -102,6 +103,7 @@ public: void performWindowOperation( Client* c, Options::WindowOperation op ); + Client* clientFactory(Workspace *ws, WId w); public slots: void setCurrentDesktop( int new_desktop ); @@ -128,8 +130,9 @@ public slots: void slotMouseEmulation(); + void slotResetAllClients(); + private slots: - void setDecorationStyle( int ); void desktopPopupAboutToShow(); void clientPopupAboutToShow(); void sendToDesktop( int ); @@ -197,6 +200,8 @@ private: QValueList cci; // -cascading Atom kwm_command; + + PluginMgr mgr; }; inline WId Workspace::rootWin() const