some bugfixes, added a window operations menu, some simple shading animation
svn path=/trunk/kdebase/kwin/; revision=34662
This commit is contained in:
parent
eb5e8e031d
commit
367d4fd0d7
10 changed files with 493 additions and 260 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ public:
|
|||
~BeClient();
|
||||
protected:
|
||||
void resizeEvent( QResizeEvent* );
|
||||
void windowWrapperShowEvent( QShowEvent* );
|
||||
void paintEvent( QPaintEvent* );
|
||||
void mousePressEvent( QMouseEvent * );
|
||||
void mouseReleaseEvent( QMouseEvent * );
|
||||
|
|
68
client.cpp
68
client.cpp
|
@ -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,12 +1348,34 @@ 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() ) );
|
||||
resize ( s );
|
||||
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();
|
||||
repaint();
|
||||
|
@ -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() );
|
||||
}
|
||||
|
|
3
client.h
3
client.h
|
@ -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* );
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
52
stdclient.h
52
stdclient.h
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
527
workspace.cpp
527
workspace.cpp
|
@ -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
|
||||
|
@ -878,166 +897,166 @@ void Workspace::randomPlacement(Client* c){
|
|||
px += step;
|
||||
py += 2*step;
|
||||
|
||||
if (px > maxRect.width()/2)
|
||||
px = maxRect.x() + step;
|
||||
if (py > maxRect.height()/2)
|
||||
py = maxRect.y() + step;
|
||||
tx = px;
|
||||
ty = py;
|
||||
if (tx + c->width() > maxRect.right()){
|
||||
tx = maxRect.right() - c->width();
|
||||
if (tx < 0)
|
||||
tx = 0;
|
||||
px = maxRect.x();
|
||||
}
|
||||
if (ty + c->height() > maxRect.bottom()){
|
||||
ty = maxRect.bottom() - c->height();
|
||||
if (ty < 0)
|
||||
ty = 0;
|
||||
py = maxRect.y();
|
||||
}
|
||||
c->move( tx, ty );
|
||||
if (px > maxRect.width()/2)
|
||||
px = maxRect.x() + step;
|
||||
if (py > maxRect.height()/2)
|
||||
py = maxRect.y() + step;
|
||||
tx = px;
|
||||
ty = py;
|
||||
if (tx + c->width() > maxRect.right()){
|
||||
tx = maxRect.right() - c->width();
|
||||
if (tx < 0)
|
||||
tx = 0;
|
||||
px = maxRect.x();
|
||||
}
|
||||
if (ty + c->height() > maxRect.bottom()){
|
||||
ty = maxRect.bottom() - c->height();
|
||||
if (ty < 0)
|
||||
ty = 0;
|
||||
py = maxRect.y();
|
||||
}
|
||||
c->move( tx, ty );
|
||||
}
|
||||
|
||||
/*!
|
||||
Place the client \a c according to a really smart placement algorithm :-)
|
||||
*/
|
||||
void Workspace::smartPlacement(Client* c){
|
||||
/*
|
||||
* SmartPlacement by Cristian Tibirna (tibirna@kde.org)
|
||||
* adapted for kwm (16-19jan98) and for kwin (16Nov1999) using (with
|
||||
* permission) ideas from fvwm, authored by
|
||||
* Anthony Martin (amartin@engr.csulb.edu).
|
||||
*/
|
||||
/*
|
||||
* SmartPlacement by Cristian Tibirna (tibirna@kde.org)
|
||||
* adapted for kwm (16-19jan98) and for kwin (16Nov1999) using (with
|
||||
* permission) ideas from fvwm, authored by
|
||||
* Anthony Martin (amartin@engr.csulb.edu).
|
||||
*/
|
||||
|
||||
const int none = 0, h_wrong = -1, w_wrong = -2; // overlap types
|
||||
long int overlap, min_overlap;
|
||||
int x_optimal, y_optimal;
|
||||
int possible;
|
||||
const int none = 0, h_wrong = -1, w_wrong = -2; // overlap types
|
||||
long int overlap, min_overlap;
|
||||
int x_optimal, y_optimal;
|
||||
int possible;
|
||||
|
||||
int cxl, cxr, cyt, cyb; //temp coords
|
||||
int xl, xr, yt, yb; //temp coords
|
||||
int cxl, cxr, cyt, cyb; //temp coords
|
||||
int xl, xr, yt, yb; //temp coords
|
||||
|
||||
// get the maximum allowed windows space
|
||||
QRect maxRect = clientArea();
|
||||
int x = maxRect.left(), y = maxRect.top();
|
||||
x_optimal = x; y_optimal = y;
|
||||
// get the maximum allowed windows space
|
||||
QRect maxRect = clientArea();
|
||||
int x = maxRect.left(), y = maxRect.top();
|
||||
x_optimal = x; y_optimal = y;
|
||||
|
||||
//client gabarit
|
||||
int ch = c->height(), cw = c->width();
|
||||
//client gabarit
|
||||
int ch = c->height(), cw = c->width();
|
||||
|
||||
bool first_pass = true; //CT lame flag. Don't like it. What else would do?
|
||||
bool first_pass = true; //CT lame flag. Don't like it. What else would do?
|
||||
|
||||
//loop over possible positions
|
||||
do {
|
||||
//test if enough room in x and y directions
|
||||
if ( y + ch > maxRect.bottom() )
|
||||
overlap = h_wrong; // this throws the algorithm to an exit
|
||||
else if( x + cw > maxRect.right() )
|
||||
overlap = w_wrong;
|
||||
else {
|
||||
overlap = none; //initialize
|
||||
//loop over possible positions
|
||||
do {
|
||||
//test if enough room in x and y directions
|
||||
if ( y + ch > maxRect.bottom() )
|
||||
overlap = h_wrong; // this throws the algorithm to an exit
|
||||
else if( x + cw > maxRect.right() )
|
||||
overlap = w_wrong;
|
||||
else {
|
||||
overlap = none; //initialize
|
||||
|
||||
cxl = x; cxr = x + cw;
|
||||
cyt = y; cyb = y + ch;
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l ) {
|
||||
if((*l)->isOnDesktop(currentDesktop()) && (*l) != desktop_client &&
|
||||
!(*l)->isIconified() && (*l) != c ) {
|
||||
cxl = x; cxr = x + cw;
|
||||
cyt = y; cyb = y + ch;
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l ) {
|
||||
if((*l)->isOnDesktop(currentDesktop()) && (*l) != desktop_client &&
|
||||
!(*l)->isIconified() && (*l) != c ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
//if windows overlap, calc the overall overlapping
|
||||
if((cxl < xr) && (cxr > xl) &&
|
||||
(cyt < yb) && (cyb > yt)) {
|
||||
xl = QMAX(cxl, xl); xr = QMIN(cxr, xr);
|
||||
yt = QMAX(cyt, yt); yb = QMIN(cyb, yb);
|
||||
overlap += (xr - xl) * (yb - yt);
|
||||
}
|
||||
//if windows overlap, calc the overall overlapping
|
||||
if((cxl < xr) && (cxr > xl) &&
|
||||
(cyt < yb) && (cyb > yt)) {
|
||||
xl = QMAX(cxl, xl); xr = QMIN(cxr, xr);
|
||||
yt = QMAX(cyt, yt); yb = QMIN(cyb, yb);
|
||||
overlap += (xr - xl) * (yb - yt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//CT first time we get no overlap we stop.
|
||||
if (overlap == none) {
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
break;
|
||||
}
|
||||
|
||||
if (first_pass) {
|
||||
first_pass = false;
|
||||
min_overlap = overlap;
|
||||
}
|
||||
//CT save the best position and the minimum overlap up to now
|
||||
else if ( overlap >= none && overlap < min_overlap) {
|
||||
min_overlap = overlap;
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
}
|
||||
|
||||
// really need to loop? test if there's any overlap
|
||||
if ( overlap > none ) {
|
||||
|
||||
possible = maxRect.right();
|
||||
if ( possible - cw > x) possible -= cw;
|
||||
|
||||
// compare to the position of each client on the current desk
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l) {
|
||||
|
||||
if ( (*l)->isOnDesktop(currentDesktop()) && (*l) != desktop_client &&
|
||||
!(*l)->isIconified() && (*l) != c ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
// if not enough room above or under the current tested client
|
||||
// determine the first non-overlapped x position
|
||||
if( y < yb && yt < ch + y ) {
|
||||
|
||||
if( yb > x )
|
||||
possible = possible < yb ? possible : yb;
|
||||
|
||||
if( xl - cw > x )
|
||||
possible = possible < xl - cw ? possible : xl - cw;
|
||||
}
|
||||
//CT first time we get no overlap we stop.
|
||||
if (overlap == none) {
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
break;
|
||||
}
|
||||
x = possible;
|
||||
}
|
||||
}
|
||||
|
||||
// ... else ==> not enough x dimension (overlap was wrong on horizontal)
|
||||
else if ( overlap == w_wrong ) {
|
||||
x = maxRect.left();
|
||||
possible = maxRect.bottom();
|
||||
|
||||
if ( possible - ch > y ) possible -= ch;
|
||||
|
||||
//test the position of each window on current desk
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for( l = clients.begin(); l != clients.end() ; ++l ) {
|
||||
if( (*l)->isOnDesktop( currentDesktop() ) && (*l) != desktop_client &&
|
||||
(*l) != c && !c->isIconified() ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
if( yb > y)
|
||||
possible = possible < yb ? possible : yb;
|
||||
|
||||
if( yt - ch > y )
|
||||
possible = possible < yt - ch ? possible : yt - ch;
|
||||
if (first_pass) {
|
||||
first_pass = false;
|
||||
min_overlap = overlap;
|
||||
}
|
||||
//CT save the best position and the minimum overlap up to now
|
||||
else if ( overlap >= none && overlap < min_overlap) {
|
||||
min_overlap = overlap;
|
||||
x_optimal = x;
|
||||
y_optimal = y;
|
||||
}
|
||||
y = possible;
|
||||
}
|
||||
}
|
||||
}
|
||||
while( overlap != none && overlap != h_wrong );
|
||||
|
||||
// place the window
|
||||
c->move( x_optimal, y_optimal );
|
||||
// really need to loop? test if there's any overlap
|
||||
if ( overlap > none ) {
|
||||
|
||||
possible = maxRect.right();
|
||||
if ( possible - cw > x) possible -= cw;
|
||||
|
||||
// compare to the position of each client on the current desk
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for(l = clients.begin(); l != clients.end() ; ++l) {
|
||||
|
||||
if ( (*l)->isOnDesktop(currentDesktop()) && (*l) != desktop_client &&
|
||||
!(*l)->isIconified() && (*l) != c ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
// if not enough room above or under the current tested client
|
||||
// determine the first non-overlapped x position
|
||||
if( y < yb && yt < ch + y ) {
|
||||
|
||||
if( yb > x )
|
||||
possible = possible < yb ? possible : yb;
|
||||
|
||||
if( xl - cw > x )
|
||||
possible = possible < xl - cw ? possible : xl - cw;
|
||||
}
|
||||
}
|
||||
x = possible;
|
||||
}
|
||||
}
|
||||
|
||||
// ... else ==> not enough x dimension (overlap was wrong on horizontal)
|
||||
else if ( overlap == w_wrong ) {
|
||||
x = maxRect.left();
|
||||
possible = maxRect.bottom();
|
||||
|
||||
if ( possible - ch > y ) possible -= ch;
|
||||
|
||||
//test the position of each window on current desk
|
||||
QValueList<Client*>::ConstIterator l;
|
||||
for( l = clients.begin(); l != clients.end() ; ++l ) {
|
||||
if( (*l)->isOnDesktop( currentDesktop() ) && (*l) != desktop_client &&
|
||||
(*l) != c && !c->isIconified() ) {
|
||||
|
||||
xl = (*l)->x(); yt = (*l)->y();
|
||||
xr = xl + (*l)->height(); yb = yt + (*l)->width();
|
||||
|
||||
if( yb > y)
|
||||
possible = possible < yb ? possible : yb;
|
||||
|
||||
if( yt - ch > y )
|
||||
possible = possible < yt - ch ? possible : yt - ch;
|
||||
}
|
||||
y = possible;
|
||||
}
|
||||
}
|
||||
}
|
||||
while( overlap != none && overlap != h_wrong );
|
||||
|
||||
// place the window
|
||||
c->move( x_optimal, y_optimal );
|
||||
|
||||
}
|
||||
|
||||
|
@ -1045,67 +1064,67 @@ 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
|
||||
int xp, yp;
|
||||
int xp, yp;
|
||||
|
||||
//CT how do I get from the 'Client' class the size that NW squarish "handle"
|
||||
int delta_x = 24;
|
||||
int delta_y = 24;
|
||||
//CT how do I get from the 'Client' class the size that NW squarish "handle"
|
||||
int delta_x = 24;
|
||||
int delta_y = 24;
|
||||
|
||||
int d = currentDesktop() - 1;
|
||||
int d = currentDesktop() - 1;
|
||||
|
||||
// get the maximum allowed windows space and desk's origin
|
||||
// (CT 20Nov1999 - is this common to all desktops?)
|
||||
QRect maxRect = clientArea();
|
||||
// get the maximum allowed windows space and desk's origin
|
||||
// (CT 20Nov1999 - is this common to all desktops?)
|
||||
QRect maxRect = clientArea();
|
||||
|
||||
// initialize often used vars: width and height of c; we gain speed
|
||||
int ch = c->height();
|
||||
int cw = c->width();
|
||||
int H = maxRect.bottom();
|
||||
int W = maxRect.right();
|
||||
int X = maxRect.left();
|
||||
int Y = maxRect.top();
|
||||
int ch = c->height();
|
||||
int cw = c->width();
|
||||
int H = maxRect.bottom();
|
||||
int W = maxRect.right();
|
||||
int X = maxRect.left();
|
||||
int Y = maxRect.top();
|
||||
|
||||
//initialize if needed
|
||||
if (re_init) {
|
||||
cci[d].pos = QPoint(X, Y);
|
||||
cci[d].col = cci[d].row = 0;
|
||||
}
|
||||
|
||||
|
||||
xp = cci[d].pos.x();
|
||||
yp = cci[d].pos.y();
|
||||
|
||||
//here to touch in case people vote for resize on placement
|
||||
if ((yp + ch ) > H) yp = Y;
|
||||
|
||||
if ((xp + cw ) > W)
|
||||
if (!yp) {
|
||||
smartPlacement(c);
|
||||
return;
|
||||
if (re_init) {
|
||||
cci[d].pos = QPoint(X, Y);
|
||||
cci[d].col = cci[d].row = 0;
|
||||
}
|
||||
else xp = X;
|
||||
|
||||
|
||||
xp = cci[d].pos.x();
|
||||
yp = cci[d].pos.y();
|
||||
|
||||
//here to touch in case people vote for resize on placement
|
||||
if ((yp + ch ) > H) yp = Y;
|
||||
|
||||
if ((xp + cw ) > W)
|
||||
if (!yp) {
|
||||
smartPlacement(c);
|
||||
return;
|
||||
}
|
||||
else xp = X;
|
||||
|
||||
//if this isn't the first window
|
||||
if ( cci[d].pos.x() != X && cci[d].pos.y() != Y ) {
|
||||
if ( xp != X && yp == Y ) xp = delta_x * (++(cci[d].col));
|
||||
if ( yp != Y && xp == X ) yp = delta_y * (++(cci[d].row));
|
||||
if ( cci[d].pos.x() != X && cci[d].pos.y() != Y ) {
|
||||
if ( xp != X && yp == Y ) xp = delta_x * (++(cci[d].col));
|
||||
if ( yp != Y && xp == X ) yp = delta_y * (++(cci[d].row));
|
||||
|
||||
// last resort: if still doesn't fit, smart place it
|
||||
if ( ((xp + cw) > W - X) || ((yp + ch) > H - Y) ) {
|
||||
smartPlacement(c);
|
||||
return;
|
||||
// last resort: if still doesn't fit, smart place it
|
||||
if ( ((xp + cw) > W - X) || ((yp + ch) > H - Y) ) {
|
||||
smartPlacement(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// place the window
|
||||
c->move( QPoint( xp, yp ) );
|
||||
// place the window
|
||||
c->move( QPoint( xp, yp ) );
|
||||
|
||||
// new position
|
||||
cci[d].pos = QPoint( xp + delta_x, yp + delta_y );
|
||||
// new position
|
||||
cci[d].pos = QPoint( xp + delta_x, yp + delta_y );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 SystemClient(this, w);
|
||||
break;
|
||||
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();
|
||||
}
|
||||
|
|
20
workspace.h
20
workspace.h
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue