some bugfixes, added a window operations menu, some simple shading animation

svn path=/trunk/kdebase/kwin/; revision=34662
This commit is contained in:
Matthias Ettrich 1999-11-22 01:57:51 +00:00
parent eb5e8e031d
commit 367d4fd0d7
10 changed files with 493 additions and 260 deletions

View file

@ -54,6 +54,7 @@ BeClient::BeClient( Workspace *ws, WId w, QWidget *parent, const char *name )
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);
@ -80,7 +81,7 @@ void BeClient::resizeEvent( QResizeEvent* e)
{
Client::resizeEvent( e );
doShape();
if ( isVisibleToTLW() ) {
if ( isVisibleToTLW() && !testWFlags( WNorthWestGravity ) ) {
// manual clearing without the titlebar (we selected WResizeNoErase )
QPainter p( this );
QRect t = titlebar->geometry();
@ -208,3 +209,8 @@ void BeClient::mouseDoubleClickEvent( QMouseEvent * e )
workspace()->requestFocus( this );
}
void BeClient::windowWrapperShowEvent( QShowEvent* )
{
doShape();
}

View file

@ -14,6 +14,7 @@ public:
~BeClient();
protected:
void resizeEvent( QResizeEvent* );
void windowWrapperShowEvent( QShowEvent* );
void paintEvent( QPaintEvent* );
void mousePressEvent( QMouseEvent * );
void mouseReleaseEvent( QMouseEvent * );

View file

@ -96,6 +96,8 @@ WindowWrapper::WindowWrapper( WId w, Client *parent, const char* name)
win = w;
setMouseTracking( TRUE );
setBackgroundColor( colorGroup().background() );
// we don't want the window to be destroyed when we are destroyed
XAddToSaveSet(qt_xdisplay(), win );
@ -733,7 +735,7 @@ void Client::mousePressEvent( QMouseEvent * e)
invertedMoveOffset = rect().bottomRight() - e->pos();
}
else if ( e->button() == RightButton ) {
workspace()->showPopup( e->globalPos(), this );
workspace()->clientPopup( this ) ->popup( e->globalPos() );
}
}
@ -1112,11 +1114,25 @@ void Client::closeWindow()
}
}
void Client::maximize( MaximizeMode /*m*/)
void Client::maximize( MaximizeMode m)
{
if ( isShade() )
setShade( FALSE );
if ( geom_restore.isNull() ) {
geom_restore = geometry();
setGeometry( workspace()->geometry() );
switch ( m ) {
case MaximizeVertical:
setGeometry( QRect( QPoint( x(), workspace()->geometry().top() ),
adjustedSize( QSize( width(), workspace()->geometry().height()) ) ) );
break;
case MaximizeHorizontal:
setGeometry( QRect( QPoint( workspace()->geometry().left(), y() ),
adjustedSize( QSize( workspace()->geometry().width(), height() ) ) ) );
break;
default:
setGeometry( QRect( workspace()->geometry().topLeft(), adjustedSize(workspace()->geometry().size()) ) );
}
maximizeChange( TRUE );
}
else {
@ -1161,6 +1177,12 @@ bool Client::eventFilter( QObject *o, QEvent * e)
break;
case QEvent::MouseButtonRelease:
break;
case QEvent::Show:
windowWrapperShowEvent( (QShowEvent*)e );
break;
case QEvent::Hide:
windowWrapperHideEvent( (QHideEvent*)e );
break;
default:
break;
}
@ -1326,11 +1348,33 @@ void Client::setShade( bool s )
shaded = s;
if (shaded ) {
int h = height();
QSize s( sizeForWindowSize( QSize( windowWrapper()->width(), 0), TRUE ) );
windowWrapper()->hide();
repaint( FALSE ); // force direct repaint
setWFlags( WNorthWestGravity );
int step = QMAX( 15, QABS( h - s.height() ) / 20 )+1;
while ( h > s.height() + step ) {
h -= step;
resize ( s.width(), h );
QApplication::syncX();
}
clearWFlags( WNorthWestGravity );
resize (s );
} else {
int h = height();
QSize s( sizeForWindowSize( windowWrapper()->size() ) );
setWFlags( WNorthWestGravity );
int step = QMAX( 15, QABS( h - s.height() ) / 30 )+1;
while ( h < s.height() - step ) {
h += step;
resize ( s.width(), h );
// assume a border
// we do not have time to wait for X to send us paint events
repaint( 0, h - step-5, width(), step+5, TRUE);
QApplication::syncX();
}
clearWFlags( WNorthWestGravity );
resize ( s );
windowWrapper()->show();
layout()->activate();
@ -1372,14 +1416,20 @@ void Client::setSticky( bool b )
if ( is_sticky == b )
return;
is_sticky = b;
if ( !is_sticky ) {
desk = workspace()->currentDesktop();
KWM::moveToDesktop( win, desk );//##### compatibility
}
if ( !is_sticky )
setDesktop( workspace()->currentDesktop() );
stickyChange( is_sticky );
}
void Client::setDesktop( int desktop)
{
if ( isOnDesktop( desktop ) )
return;
desk = desktop;
KWM::moveToDesktop( win, desk );//##### compatibility
}
void Client::getIcons()
{
icon_pix = KWM::icon( win, 32, 32 ); // TODO sizes from workspace
@ -1427,10 +1477,10 @@ void Client::setMask( const QRegion & reg)
}
NoBorderClient::NoBorderClient( Workspace *ws, WId w, QWidget *parent=0, const char *name=0 )
: Client( ws, w, parent, name )
{
setBackgroundColor( yellow );
QHBoxLayout* h = new QHBoxLayout( this );
h->addWidget( windowWrapper() );
}

View file

@ -102,6 +102,7 @@ public:
void setActive( bool );
int desktop() const;
void setDesktop( int );
bool isOnDesktop( int d ) const;
bool isShade() const;
@ -151,6 +152,8 @@ protected:
void mouseReleaseEvent( QMouseEvent * );
void mouseMoveEvent( QMouseEvent * );
void resizeEvent( QResizeEvent * );
virtual void windowWrapperShowEvent( QShowEvent* ){}
virtual void windowWrapperHideEvent( QHideEvent* ){}
void enterEvent( QEvent * );
void leaveEvent( QEvent * );
void showEvent( QShowEvent* );

View file

@ -6,3 +6,7 @@
keys->insertItem(i18n("Switch to desktop 6"), "Switch to desktop 6" ,"CTRL+F6");
keys->insertItem(i18n("Switch to desktop 7"), "Switch to desktop 7" ,"CTRL+F7");
keys->insertItem(i18n("Switch to desktop 8"), "Switch to desktop 8" ,"CTRL+F8");
keys->insertItem(i18n("Window operations menu"), "Pop-up window operations menu" ,"ALT+F3");
keys->insertItem(i18n("Window close"),"Window close" ,"ALT+F4");

View file

@ -188,6 +188,8 @@ StdClient::StdClient( Workspace *ws, WId w, QWidget *parent, const char *name )
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, 2);
@ -197,7 +199,7 @@ StdClient::StdClient( Workspace *ws, WId w, QWidget *parent, const char *name )
button[1] = new QToolButton( this );
button[2] = new QToolButton( this );
button[3] = new QToolButton( this );
button[4] = new QToolButton( this );
button[4] = new ThreeButtonButton( this );
button[5] = new QToolButton( this );
QHBoxLayout* hb = new QHBoxLayout;
@ -225,6 +227,11 @@ StdClient::StdClient( Workspace *ws, WId w, QWidget *parent, const char *name )
button[0]->setIconSet(isActive() ? *menu_pix : *dis_menu_pix);
else
button[0]->setIconSet( miniIcon() );
connect( button[0], SIGNAL( pressed() ), this, SLOT( menuButtonPressed() ) );
button[0]->setPopupDelay( 0 );
button[0]->setPopup( workspace()->clientPopup( this ) );
button[1]->setIconSet(isSticky() ? isActive() ? *pindown_pix : *dis_pindown_pix :
isActive() ? *pinup_pix : *dis_pinup_pix );
connect( button[1], SIGNAL( clicked() ), this, ( SLOT( toggleSticky() ) ) );
@ -234,7 +241,7 @@ StdClient::StdClient( Workspace *ws, WId w, QWidget *parent, const char *name )
button[3]->setIconSet(isActive() ? *minimize_pix : *dis_minimize_pix);
connect( button[3], SIGNAL( clicked() ), this, ( SLOT( iconify() ) ) );
button[4]->setIconSet(isActive() ? *maximize_pix : *dis_maximize_pix);
connect( button[4], SIGNAL( clicked() ), this, ( SLOT( maximize() ) ) );
connect( button[4], SIGNAL( clicked(int) ), this, ( SLOT( maxButtonClicked(int) ) ) );
button[5]->setIconSet(isActive() ? *close_pix : *dis_close_pix);
connect( button[5], SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) );
@ -267,7 +274,7 @@ void StdClient::resizeEvent( QResizeEvent* e)
QRegion r = rr.subtract( QRect( t.x()+1, 0, t.width()-2, 1 ) );
setMask( r );
if ( isVisibleToTLW() ) {
if ( isVisibleToTLW() && !testWFlags( WNorthWestGravity )) {
// manual clearing without the titlebar (we selected WResizeNoErase )
QPainter p( this );
r = rr.subtract( t );
@ -347,3 +354,27 @@ void StdClient::iconChange()
button[0]->repaint( FALSE );
}
/*!
Indicates that the menu button has been clicked
*/
void StdClient::menuButtonPressed()
{
(void ) workspace()->clientPopup( this ); //trigger the popup menu
}
void StdClient::maxButtonClicked( int button )
{
switch ( button ){
case MidButton:
maximize( MaximizeVertical );
break;
case RightButton:
maximize( MaximizeHorizontal );
break;
default: //LeftButton:
maximize( MaximizeFull );
break;
}
}

View file

@ -1,7 +1,7 @@
#ifndef STDCLIENT_H
#define STDCLIENT_H
#include "client.h"
class QToolButton;
#include <qtoolbutton.h>
class QLabel;
class QSpacerItem;
@ -23,10 +23,60 @@ protected:
void stickyChange( bool );
void activeChange( bool );
private slots:
void menuButtonPressed();
void maxButtonClicked( int );
private:
QToolButton* button[6];
QSpacerItem* titlebar;
};
/*
Like QToolButton, but provides a clicked(int) signals that
has the last pressed mouse button as argument
*/
class ThreeButtonButton: public QToolButton
{
Q_OBJECT
public:
ThreeButtonButton ( QWidget *parent = 0, const char* name = 0)
: QToolButton( parent, name )
{
connect( this, SIGNAL( clicked() ), this, SLOT( handleClicked() ) );
}
~ThreeButtonButton ()
{}
signals:
void clicked( int );
protected:
void mousePressEvent( QMouseEvent* e )
{
last_button = e->button();
QMouseEvent me ( e->type(), e->pos(), e->globalPos(), LeftButton, e->state() );
QToolButton::mousePressEvent( &me );
}
void mouseReleaseEvent( QMouseEvent* e )
{
QMouseEvent me ( e->type(), e->pos(), e->globalPos(), LeftButton, e->state() );
QToolButton::mouseReleaseEvent( &me );
}
private slots:
void handleClicked()
{
emit clicked( last_button );
}
private:
int last_button;
};
#endif

View file

@ -183,6 +183,7 @@ SystemClient::SystemClient( Workspace *ws, WId w, QWidget *parent,
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->addRowSpacing(2, 6);
button[0] = new SystemButton(this, "close", close_bits);
@ -224,7 +225,7 @@ void SystemClient::resizeEvent( QResizeEvent* e)
{
Client::resizeEvent( e );
if ( isVisibleToTLW() ) {
if ( isVisibleToTLW() && !testWFlags( WNorthWestGravity )) {
QPainter p( this );
QRect t = titlebar->geometry();
t.setTop( 0 );

View file

@ -106,10 +106,6 @@ Workspace::Workspace()
XChangeProperty(qt_xdisplay(), qt_xrootwin(), atoms->kwm_running, atoms->kwm_running, 32,
PropModeAppend, (unsigned char*) &data, 1);
init();
control_grab = FALSE;
tab_grab = FALSE;
tab_box = new TabBox( this );
keys = 0;
grabKey(XK_Tab, Mod1Mask);
grabKey(XK_Tab, Mod1Mask | ShiftMask);
@ -117,6 +113,11 @@ Workspace::Workspace()
grabKey(XK_Tab, ControlMask | ShiftMask);
createKeybindings();
init();
control_grab = FALSE;
tab_grab = FALSE;
tab_box = new TabBox( this );
}
Workspace::Workspace( WId rootwin )
@ -148,6 +149,9 @@ void Workspace::init()
desktop_client = 0;
current_desktop = 0;
number_of_desktops = 0;
popup = 0;
desk_popup = 0;
popup_client = 0;
setNumberOfDesktops( 4 ); // TODO options
setCurrentDesktop( 1 );
@ -184,7 +188,6 @@ void Workspace::init()
}
XFree((void *) wins);
XUngrabServer( qt_xdisplay() );
popup = 0;
propagateClients();
//CT initialize the cascading info
@ -803,48 +806,64 @@ void Workspace::clientHidden( Client* c )
}
void Workspace::showPopup( const QPoint& pos, Client* c)
QPopupMenu* Workspace::clientPopup( Client* c )
{
// experimental!!!
popup_client = c;
if ( !popup ) {
popup = new QPopupMenu;
popup->setCheckable( TRUE );
connect( popup, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) );
connect( popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) );
// I wish I could use qt-2.1 features here..... grmblll
QPopupMenu* deco = new QPopupMenu( popup );
deco->insertItem("KDE Classic", 100 );
deco->insertItem("Be-like style", 101 );
deco->insertItem("System style", 102 );
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 );
popup->insertItem("Decoration", deco );
}
popup_client = c;
// TODO customize popup for the client
int ret = popup->exec( pos );
KConfig *config = KGlobal::config();
config->setGroup("style");
switch( ret ) {
case 100:
config->writeEntry("Plugin", "standard");
setDecoration( 0 );
break;
case 101:
config->writeEntry("Plugin", "be");
setDecoration( 1 );
break;
case 102:
config->writeEntry("Plugin", "system");
setDecoration( 2 );
break;
default:
break;
}
config->sync();
popup_client = 0;
ret = 0;
desk_popup = new QPopupMenu( popup );
desk_popup->setCheckable( TRUE );
connect( desk_popup, SIGNAL( activated(int) ), this, SLOT( sendToDesktop(int) ) );
connect( desk_popup, SIGNAL( aboutToShow() ), this, SLOT( desktopPopupAboutToShow() ) );
popupIdMove = popup->insertItem( i18n("&Move") );
popupIdSize = popup->insertItem( i18n("&Size") );
popupIdMinimize = popup->insertItem( i18n("&Mi&nimize") );
popupIdMaximize = popup->insertItem( i18n("Ma&ximize") );
// popupIdFullscreen = popup->insertItem( i18n("&Fullscreen") );
popupIdFullscreen = 0;
popupIdShade = popup->insertItem( i18n("Sh&ade") );
popup->insertSeparator();
popup->insertItem(i18n("&Decoration"), deco );
popup->insertItem(i18n("&To desktop"), desk_popup );
popup->insertSeparator();
QString k = KAccel::keyToString( keys->currentKey( "Window close" ), true );
popupIdClose = popup->insertItem(i18n("&Close")+'\t'+k );
}
return popup;
}
void Workspace::clientPopupActivated( int id )
{
if ( !popup_client )
return;
if ( id == popupIdClose )
popup_client->closeWindow();
else if ( id == popupIdMaximize )
popup_client->maximize();
else if ( id == popupIdMinimize )
popup_client->iconify();
else if ( id == popupIdFullscreen )
popup_client->fullScreen();
else if ( id == popupIdShade )
popup_client->setShade( !popup_client->isShade() );
}
/*!
Places the client \a c according to the workspace's layout policy
@ -1045,7 +1064,7 @@ void Workspace::smartPlacement(Client* c){
Place windows in a cascading order, remembering positions for each desktop
*/
void Workspace::cascadePlacement (Client* c, bool re_init) {
/* cascadePlacement by Cristian Tibirna (tibirna@kde.org) (30Jan98)
/* cascadePlacement by Cristian Tibirna (tibirna@kde.org) (30Jan98)
*/
// work coords
@ -1270,7 +1289,7 @@ void Workspace::makeFullScreen( Client* )
// experimental
void Workspace::setDecoration( int deco )
void Workspace::setDecorationStyle( int deco )
{
if ( !popup_client )
return;
@ -1283,15 +1302,19 @@ void Workspace::setDecoration( int deco )
c->hide();
c->releaseWindow();
KWM::moveToDesktop( w, c->desktop() );
KConfig* config = KGlobal::config();
switch ( deco ) {
case 1:
c = new BeClient( this, w);
break;
case 2:
c = new BeClient( this, w);
config->writeEntry("Plugin", "Be");
break;
case 3:
c = new SystemClient(this, w);
config->writeEntry("Plugin", "system");
break;
default:
c = new StdClient( this, w );
config->writeEntry("Plugin", "standard");
}
clients.append( c );
stacking_order.append( c );
@ -1430,6 +1453,9 @@ void Workspace::createKeybindings(){
keys->connectItem( "Switch to desktop 7", this, SLOT( slotSwitchDesktop7() ));
keys->connectItem( "Switch to desktop 8", this, SLOT( slotSwitchDesktop8() ));
keys->connectItem( "Pop-up window operations menu", this, SLOT( slotWindowOperations() ) );
keys->connectItem( "Window close", this, SLOT( slotWindowClose() ) );
keys->readSettings();
}
@ -1457,3 +1483,50 @@ void Workspace::slotSwitchDesktop7(){
void Workspace::slotSwitchDesktop8(){
setCurrentDesktop(8);
}
void Workspace::desktopPopupAboutToShow()
{
if ( !desk_popup )
return;
desk_popup->clear();
int id;
for ( int i = 1; i <= numberOfDesktops(); i++ ) {
id = desk_popup->insertItem( QString("&")+QString::number(i ), i );
if ( popup_client && popup_client->desktop() == i )
desk_popup->setItemChecked( id, TRUE );
}
}
void Workspace::clientPopupAboutToShow()
{
if ( !popup_client || !popup )
return;
popup->setItemChecked( popupIdMaximize, popup_client->isMaximized() );
popup->setItemChecked( popupIdShade, popup_client->isShade() );
}
void Workspace::sendToDesktop( int desk )
{
if ( !popup_client )
return;
if ( popup_client->isOnDesktop( desk ) )
return;
popup_client->setDesktop( desk );
popup_client->hide();
}
void Workspace::slotWindowOperations()
{
if ( !active_client )
return;
QPopupMenu* p = clientPopup( active_client );
p->popup( active_client->mapToGlobal( active_client->windowWrapper()->geometry().topLeft() ) );
}
void Workspace::slotWindowClose()
{
if ( !popup_client )
return;
popup_client->closeWindow();
}

View file

@ -4,6 +4,7 @@
#include <qwidget.h>
#include <qapplication.h>
#include <qpopupmenu.h>
#include <qguardedptr.h>
#include <qvaluelist.h>
#include <X11/Xlib.h>
@ -73,7 +74,6 @@ public:
void clientHidden( Client* );
int currentDesktop() const;
void setCurrentDesktop( int new_desktop );
int numberOfDesktops() const;
void setNumberOfDesktops( int n );
@ -90,7 +90,7 @@ public:
Client* topClientOnDesktop( int fromLayer = 0, int toLayer = 0) const;
void showPopup( const QPoint&, Client* );
QPopupMenu* clientPopup( Client* );
void setDesktopClient( Client* );
@ -99,6 +99,7 @@ public:
bool iconifyMeansWithdraw( Client* );
public slots:
void setCurrentDesktop( int new_desktop );
// keybindings
void slotSwitchDesktop1();
void slotSwitchDesktop2();
@ -109,6 +110,16 @@ public slots:
void slotSwitchDesktop7();
void slotSwitchDesktop8();
void slotWindowOperations();
void slotWindowClose();
private slots:
void setDecorationStyle( int );
void desktopPopupAboutToShow();
void clientPopupAboutToShow();
void sendToDesktop( int );
void clientPopupActivated( int );
protected:
bool keyPress( XKeyEvent key );
@ -128,7 +139,11 @@ private:
bool tab_grab;
TabBox* tab_box;
void freeKeyboard(bool pass);
QGuardedPtr<Client> popup_client;
QPopupMenu *popup;
int popupIdMove, popupIdSize, popupIdMinimize,popupIdMaximize,
popupIdShade, popupIdFullscreen,popupIdClose;
QPopupMenu *desk_popup;
Client* should_get_focus;
void raiseTransientsOf( ClientList& safeset, Client* c );
@ -142,7 +157,6 @@ private:
int number_of_desktops;
Client* findClientWidthId( WId w ) const;
Client* popup_client;
QWidget* desktop_widget;
//experimental