more experimental stuff
svn path=/trunk/kdebase/kwin/; revision=29737
This commit is contained in:
parent
fd7f3549ac
commit
75f321c4c0
8 changed files with 216 additions and 44 deletions
|
@ -4,8 +4,8 @@ LDFLAGS = $(all_libraries) $(KDE_RPATH)
|
|||
|
||||
bin_PROGRAMS = kwin
|
||||
|
||||
kwin_SOURCES = atoms.cpp beclient.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp
|
||||
kwin_SOURCES = atoms.cpp beclient.cpp client.cpp main.cpp stdclient.cpp workspace.cpp tabbox.cpp options.cpp
|
||||
|
||||
kwin_LDADD = $(LIB_KDECORE)
|
||||
|
||||
METASOURCES = AUTO
|
||||
METASOURCES = AUTO
|
||||
|
|
188
client.cpp
188
client.cpp
|
@ -1,8 +1,10 @@
|
|||
#include <qapplication.h>
|
||||
#include <qcursor.h>
|
||||
#include <qbitmap.h>
|
||||
#include <qimage.h>
|
||||
#include <qwmatrix.h>
|
||||
#include <qlayout.h>
|
||||
#include <qpainter.h>
|
||||
#include "workspace.h"
|
||||
#include "client.h"
|
||||
#include "atoms.h"
|
||||
|
@ -14,6 +16,32 @@
|
|||
|
||||
extern Atom qt_wm_state;
|
||||
|
||||
static QImage* imgClient = 0;
|
||||
static QPixmap* pmBackground = 0;
|
||||
static QImage* imgBackground = 0;
|
||||
|
||||
static QRect* visible_bound = 0;
|
||||
|
||||
void Client::drawbound( const QRect& geom )
|
||||
{
|
||||
if ( visible_bound )
|
||||
*visible_bound = geom;
|
||||
else
|
||||
visible_bound = new QRect( geom );
|
||||
QPainter p ( workspace()->desktopWidget() );
|
||||
p.setPen( QPen( Qt::white, 5 ) );
|
||||
p.setRasterOp( Qt::XorROP );
|
||||
p.drawRect( geom );
|
||||
}
|
||||
void Client::clearbound()
|
||||
{
|
||||
if ( !visible_bound )
|
||||
return;
|
||||
drawbound( *visible_bound );
|
||||
delete visible_bound;
|
||||
visible_bound = 0;
|
||||
}
|
||||
|
||||
|
||||
static void sendClientMessage(Window w, Atom a, long x){
|
||||
XEvent ev;
|
||||
|
@ -361,6 +389,7 @@ bool WindowWrapper::x11Event( XEvent * e)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\class Client client.h
|
||||
|
||||
|
@ -392,6 +421,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
|
||||
mode = Nowhere;
|
||||
buttonDown = FALSE;
|
||||
moveResizeMode = FALSE;
|
||||
setMouseTracking( TRUE );
|
||||
|
||||
active = FALSE;
|
||||
|
@ -400,7 +430,7 @@ Client::Client( Workspace *ws, WId w, QWidget *parent, const char *name, WFlags
|
|||
is_sticky = FALSE;
|
||||
|
||||
ignore_unmap = 0;
|
||||
|
||||
|
||||
getIcons();
|
||||
getWindowProtocols();
|
||||
getWmNormalHints(); // get xSizeHint
|
||||
|
@ -824,6 +854,30 @@ void Client::mouseReleaseEvent( QMouseEvent * e)
|
|||
{
|
||||
if ( e->button() == LeftButton ) {
|
||||
buttonDown = FALSE;
|
||||
if ( moveResizeMode ) {
|
||||
clearbound();
|
||||
if ( isMove() && options->moveMode == Options::HalfTransparent ) {
|
||||
QPainter p ( workspace()->desktopWidget() );
|
||||
if ( !mask.isNull() ) {
|
||||
QRegion r( mask );
|
||||
r.translate( x(), y() );
|
||||
p.setClipRegion( r );
|
||||
}
|
||||
p.drawImage( x(), y(), *imgClient);
|
||||
}
|
||||
delete imgClient;
|
||||
imgClient = 0;
|
||||
delete imgBackground;
|
||||
imgBackground = 0;
|
||||
delete pmBackground;
|
||||
pmBackground = 0;
|
||||
if ( ( isMove() && options->moveMode != Options::Opaque )
|
||||
|| ( isResize() && options->resizeMode != Options::Opaque ) )
|
||||
XUngrabServer( qt_xdisplay() );
|
||||
setGeometry( geom );
|
||||
moveResizeMode = FALSE;
|
||||
releaseMouse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -838,6 +892,39 @@ void Client::mouseMoveEvent( QMouseEvent * e)
|
|||
return;
|
||||
}
|
||||
|
||||
QRect oldGeom( geom );
|
||||
|
||||
if ( !moveResizeMode )
|
||||
{
|
||||
QPoint p( e->pos() - moveOffset );
|
||||
if ( QABS( p.x() >= 4) || QABS( p.y() ) >= 4 ) {
|
||||
moveResizeMode = TRUE;
|
||||
grabMouse( cursor() ); // to keep the right cursor
|
||||
if ( ( isMove() && options->moveMode != Options::Opaque )
|
||||
|| ( isResize() && options->resizeMode != Options::Opaque ) )
|
||||
XGrabServer( qt_xdisplay() );
|
||||
|
||||
if ( isMove() && options->moveMode == Options::HalfTransparent ) {
|
||||
imgClient = new QImage( QPixmap::grabWidget( this ).convertToImage() );
|
||||
// TODO SLOW!!!
|
||||
pmBackground = new QPixmap( QPixmap::grabWindow( qt_xrootwin() ));
|
||||
imgBackground = new QImage( pmBackground->convertToImage() );
|
||||
QRect ww( windowWrapper()->geometry() );
|
||||
ww.moveBy( x(), y() );
|
||||
ww = ww.intersect( workspace()->geometry() );
|
||||
ww.moveBy( -x(), -y() );
|
||||
bitBlt( imgClient,
|
||||
ww.x(),
|
||||
ww.y(),
|
||||
imgBackground,
|
||||
x()+ww.x(), y()+ww.y(), ww.width(), ww.height() );
|
||||
oldGeom.setRect(0,0,0,0);
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mode != Center && shaded ) {
|
||||
wwrap->show();
|
||||
workspace()->requestFocus( this );
|
||||
|
@ -846,22 +933,6 @@ void Client::mouseMoveEvent( QMouseEvent * e)
|
|||
|
||||
QPoint globalPos = e->pos() + geometry().topLeft();
|
||||
|
||||
// TODO for MDI this has to be based on the parent window!
|
||||
// QPoint p = parentWidget()->mapFromGlobal( e->globalPos() );
|
||||
|
||||
// if ( !parentWidget()->rect().contains(p) ) {
|
||||
// if ( p.x() < 0 )
|
||||
// p.rx() = 0;
|
||||
// if ( p.y() < 0 )
|
||||
// p.ry() = 0;
|
||||
// if ( p.x() > parentWidget()->width() )
|
||||
// p.rx() = parentWidget()->width();
|
||||
// if ( p.y() > parentWidget()->height() )
|
||||
// p.ry() = parentWidget()->height();
|
||||
// }
|
||||
|
||||
// if ( testWState(WState_ConfigPending) )
|
||||
// return;
|
||||
|
||||
QPoint p = globalPos + invertedMoveOffset;
|
||||
|
||||
|
@ -872,7 +943,7 @@ void Client::mouseMoveEvent( QMouseEvent * e)
|
|||
QPoint mp( geometry().right() - mpsize.width() + 1,
|
||||
geometry().bottom() - mpsize.height() + 1 );
|
||||
|
||||
QRect geom = geometry();
|
||||
geom = geometry();
|
||||
switch ( mode ) {
|
||||
case TopLeft:
|
||||
geom = QRect( mp, geometry().bottomRight() ) ;
|
||||
|
@ -905,12 +976,74 @@ void Client::mouseMoveEvent( QMouseEvent * e)
|
|||
break;
|
||||
}
|
||||
|
||||
if ( geom.size() != size() ) {
|
||||
geom.setSize( adjustedSize( geom.size() ) );
|
||||
setGeometry( geom );
|
||||
if ( isResize() && geom.size() != size() ) {
|
||||
if (options->resizeMode == Options::Opaque ) {
|
||||
geom.setSize( adjustedSize( geom.size() ) );
|
||||
setGeometry( geom );
|
||||
} else if ( options->resizeMode == Options::Transparent ) {
|
||||
clearbound();
|
||||
drawbound( geom );
|
||||
}
|
||||
}
|
||||
else if ( isMove() && geom.topLeft() != geometry().topLeft() ) {
|
||||
switch ( options->moveMode ) {
|
||||
case Options::Opaque:
|
||||
move( geom.topLeft() );
|
||||
break;
|
||||
case Options::Transparent:
|
||||
clearbound();
|
||||
drawbound( geom );
|
||||
break;
|
||||
case Options::HalfTransparent:
|
||||
{
|
||||
QPainter p ( workspace()->desktopWidget() );
|
||||
QRegion now( geom );
|
||||
if ( !mask.isNull() ) {
|
||||
QRegion r( mask );
|
||||
r.translate( geom.x(), geom.y() );
|
||||
now = r;
|
||||
}
|
||||
if ( !oldGeom.isEmpty() ) {
|
||||
QRegion r( oldGeom );
|
||||
r = r.subtract( now );
|
||||
p.setClipRegion( r );
|
||||
p.drawPixmap( oldGeom.x(), oldGeom.y(),
|
||||
*pmBackground,
|
||||
oldGeom.x(), oldGeom.y(),
|
||||
oldGeom.width(), oldGeom.height() );
|
||||
}
|
||||
p.setClipRegion( now );
|
||||
QImage img ( *imgClient );
|
||||
img.detach();
|
||||
QRect visibleRect = QRect( 0, 0,
|
||||
workspace()->geometry().width(),
|
||||
workspace()->geometry().height() ).intersect( geom );
|
||||
for ( int i=visibleRect.top(); i<=visibleRect.bottom(); i++ ) {
|
||||
uint *p = (uint *)imgBackground->scanLine(i);
|
||||
uint *end = p + visibleRect.right();
|
||||
p += visibleRect.left();
|
||||
uint *pimg = (uint *)img.scanLine(i - geom.top() );
|
||||
pimg += visibleRect.left() - geom.left();
|
||||
while ( p <= end ) {
|
||||
int r = (*p&0x00ff0000) >> 16;
|
||||
int r2 = (*pimg&0x00ff0000) >> 16;
|
||||
int g = (*p&0x0000ff00) >> 8;
|
||||
int g2 = (*pimg&0x0000ff00) >> 8;
|
||||
int b = (*p&0x000000ff );
|
||||
int b2 = (*pimg&0x000000ff );
|
||||
*pimg = ( ( (r+2*r2)/3 ) << 16 )
|
||||
+ ( ( (g+2*g2)/3 ) << 8 )
|
||||
+ ( (b+2*b2)/3 );
|
||||
p++;
|
||||
pimg++;
|
||||
}
|
||||
}
|
||||
|
||||
p.drawImage( geom.x(), geom.y(), img );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( geom.topLeft() != geometry().topLeft() )
|
||||
move( geom.topLeft() );
|
||||
|
||||
}
|
||||
|
||||
|
@ -1451,6 +1584,15 @@ void Client::takeFocus()
|
|||
}
|
||||
|
||||
|
||||
/*!\reimp
|
||||
*/
|
||||
void Client::setMask( const QRegion & reg)
|
||||
{
|
||||
mask = reg;
|
||||
QWidget::setMask( reg );
|
||||
}
|
||||
|
||||
|
||||
NoBorderClient::NoBorderClient( Workspace *ws, WId w, QWidget *parent=0, const char *name=0 )
|
||||
: Client( ws, w, parent, name )
|
||||
{
|
||||
|
|
15
client.h
15
client.h
|
@ -119,6 +119,12 @@ public:
|
|||
|
||||
void takeFocus();
|
||||
|
||||
void setMask( const QRegion & );
|
||||
|
||||
// transparent stuff
|
||||
virtual void drawbound( const QRect& geom );
|
||||
virtual void clearbound();
|
||||
|
||||
public slots:
|
||||
void iconify();
|
||||
void closeWindow();
|
||||
|
@ -175,6 +181,13 @@ private:
|
|||
Workspace* wspace;
|
||||
int desk;
|
||||
bool buttonDown;
|
||||
bool moveResizeMode;
|
||||
bool isMove() const {
|
||||
return moveResizeMode && mode == Center;
|
||||
}
|
||||
bool isResize() const {
|
||||
return !isMove();
|
||||
}
|
||||
MousePosition mode;
|
||||
QPoint moveOffset;
|
||||
QPoint invertedMoveOffset;
|
||||
|
@ -185,6 +198,7 @@ private:
|
|||
bool active;
|
||||
int ignore_unmap;
|
||||
QRect original_geometry;
|
||||
QRect geom; //### TODO
|
||||
bool shaded;
|
||||
WId transient_for;
|
||||
bool is_sticky;
|
||||
|
@ -195,6 +209,7 @@ private:
|
|||
QPixmap icon_pix;
|
||||
QPixmap miniicon_pix;
|
||||
QRect geom_restore;
|
||||
QRegion mask;
|
||||
};
|
||||
|
||||
inline WId Client::window() const
|
||||
|
|
BIN
kwin
Executable file
BIN
kwin
Executable file
Binary file not shown.
1
kwin.pro
1
kwin.pro
|
@ -12,6 +12,7 @@ SOURCES = atoms.cpp \
|
|||
beclient.cpp \
|
||||
client.cpp \
|
||||
main.cpp \
|
||||
options.cpp \
|
||||
stdclient.cpp \
|
||||
tabbox.cpp \
|
||||
workspace.cpp
|
||||
|
|
22
options.h
22
options.h
|
@ -8,38 +8,40 @@ public:
|
|||
/*!
|
||||
Different focus policies:
|
||||
<ul>
|
||||
|
||||
|
||||
<li>ClickToFocus - Clicking into a window activates it. This is
|
||||
also the default.
|
||||
|
||||
|
||||
<li>FocusFollowsMouse - Moving the mouse pointer actively onto a
|
||||
window activates it.
|
||||
|
||||
|
||||
<li>FocusUnderMouse - The window that happens to be under the
|
||||
mouse pointer becomes active.
|
||||
|
||||
|
||||
<li>FocusStricklyUnderMouse - Only the window under the mouse
|
||||
pointer is active. If the mouse points nowhere, nothing has the
|
||||
focus. In practice, this is the same as FocusUnderMouse, since
|
||||
kdesktop can take the focus.
|
||||
|
||||
|
||||
Note that FocusUnderMouse and FocusStricklyUnderMouse are not
|
||||
particulary useful. They are only provided for old-fashined
|
||||
die-hard UNIX people ;-)
|
||||
|
||||
|
||||
</ul>
|
||||
*/
|
||||
enum FocusPolicy { ClickToFocus, FocusFollowsMouse, FocusUnderMouse, FocusStricklyUnderMouse };
|
||||
FocusPolicy focusPolicy;
|
||||
|
||||
enum MoveResizeMode { Transparent, Opaque, HalfTransparent };
|
||||
|
||||
MoveResizeMode resizeMode;
|
||||
MoveResizeMode moveMode;
|
||||
|
||||
bool focusPolicyIsReasonable() {
|
||||
return focusPolicy == ClickToFocus || focusPolicy == FocusFollowsMouse;
|
||||
}
|
||||
|
||||
Options(){
|
||||
focusPolicy = ClickToFocus;
|
||||
}
|
||||
|
||||
Options();
|
||||
};
|
||||
|
||||
extern Options* options;
|
||||
|
|
|
@ -36,6 +36,7 @@ Workspace::Workspace()
|
|||
root = qt_xrootwin(); // no MDI for now
|
||||
|
||||
(void) QApplication::desktop(); // trigger creation of desktop widget
|
||||
desktop_widget = new QWidget(0, "desktop_widget", Qt::WType_Desktop | Qt::WPaintUnclipped );
|
||||
|
||||
// select windowmanager privileges
|
||||
XSelectInput(qt_xdisplay(), root,
|
||||
|
@ -162,9 +163,12 @@ bool Workspace::workspaceEvent( XEvent * e )
|
|||
case DestroyNotify:
|
||||
return destroyClient( findClient( e->xdestroywindow.window ) );
|
||||
case MapRequest:
|
||||
qDebug("map request");
|
||||
if ( e->xmaprequest.parent == root ) {
|
||||
qDebug("map request on root window");
|
||||
c = findClient( e->xmaprequest.window );
|
||||
if ( !c ) {
|
||||
qDebug("didn't find a client, make a new one");
|
||||
c = clientFactory( this, e->xmaprequest.window );
|
||||
if ( root != qt_xrootwin() ) {
|
||||
// TODO may use QWidget:.create
|
||||
|
@ -640,33 +644,33 @@ void Workspace::clientHidden( Client* c )
|
|||
|
||||
void Workspace::showPopup( const QPoint& pos, Client* c)
|
||||
{
|
||||
// experimental!!!
|
||||
|
||||
// experimental!!!
|
||||
|
||||
if ( !popup ) {
|
||||
popup = new QPopupMenu;
|
||||
|
||||
// I wish I could use qt-2.1 features here..... grmblll
|
||||
// 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 );
|
||||
|
||||
|
||||
popup->insertItem("Decoration", deco );
|
||||
}
|
||||
popup_client = c;
|
||||
// TODO customize popup for the client
|
||||
int ret = popup->exec( pos );
|
||||
|
||||
|
||||
switch( ret ) {
|
||||
case 100:
|
||||
setDecoration( 0 );
|
||||
break;
|
||||
case 101:
|
||||
setDecoration( 1 );
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
popup_client = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -803,7 +807,7 @@ void Workspace::switchDesktop( int new_desktop ){
|
|||
if (new_desktop == current_desktop )
|
||||
return;
|
||||
|
||||
/*
|
||||
/*
|
||||
optimized Desktop switching: unmapping done from back to front
|
||||
mapping done from front to back => less exposure events
|
||||
*/
|
||||
|
@ -857,3 +861,8 @@ void Workspace::setDecoration( int deco )
|
|||
activateClient( c );
|
||||
}
|
||||
|
||||
|
||||
QWidget* Workspace::desktopWidget()
|
||||
{
|
||||
return desktop_widget;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
|
||||
int currentDesktop() const;
|
||||
int numberOfDesktops() const;
|
||||
|
||||
QWidget* desktopWidget();
|
||||
|
||||
void grabKey(KeySym keysym, unsigned int mod);
|
||||
|
||||
|
@ -87,7 +89,8 @@ private:
|
|||
int current_desktop;
|
||||
|
||||
Client* popup_client;
|
||||
|
||||
QWidget* desktop_widget;
|
||||
|
||||
//experimental
|
||||
void setDecoration( int deco );
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue