I have a strange feeling nobody will be bothered enough to spend
time with non-composited minimize/shade animations. svn path=/branches/work/kwin_composite/; revision=633222icc-effect-5.14.5
parent
82c96c4bc7
commit
a5e508590a
|
@ -193,8 +193,10 @@ Effects TODO
|
||||||
|
|
||||||
+ minimize/shade effects
|
+ minimize/shade effects
|
||||||
- to replace the ones from KWin core
|
- to replace the ones from KWin core
|
||||||
- Client::animateMinimizeOrUnminimize()
|
/ - minimizing
|
||||||
- Client::setShade()
|
- check support for it and the avoid_animation flag
|
||||||
|
+ - shading
|
||||||
|
- shading will probably need special support
|
||||||
|
|
||||||
/ zoom effect
|
/ zoom effect
|
||||||
- enlarge a portion of the screen
|
- enlarge a portion of the screen
|
||||||
|
|
168
client.cpp
168
client.cpp
|
@ -558,10 +558,6 @@ void Client::minimize( bool avoid_animation )
|
||||||
|
|
||||||
Notify::raise( Notify::Minimize );
|
Notify::raise( Notify::Minimize );
|
||||||
|
|
||||||
// SELI mainClients().isEmpty() ??? - and in unminimize() too
|
|
||||||
if ( mainClients().isEmpty() && isOnCurrentDesktop() && isShown( true ) && !avoid_animation )
|
|
||||||
animateMinimizeOrUnminimize( true ); // was visible or shaded
|
|
||||||
|
|
||||||
minimized = true;
|
minimized = true;
|
||||||
|
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
|
@ -569,7 +565,7 @@ void Client::minimize( bool avoid_animation )
|
||||||
workspace()->updateMinimizedOfTransients( this );
|
workspace()->updateMinimizedOfTransients( this );
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
workspace()->updateFocusChains( this, Workspace::FocusChainMakeLast );
|
workspace()->updateFocusChains( this, Workspace::FocusChainMakeLast );
|
||||||
if( effects )
|
if( effects && !avoid_animation ) // TODO shouldn't it tell effects at least about the change?
|
||||||
effects->windowMinimized( effectWindow());
|
effects->windowMinimized( effectWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,16 +576,11 @@ void Client::unminimize( bool avoid_animation )
|
||||||
|
|
||||||
Notify::raise( Notify::UnMinimize );
|
Notify::raise( Notify::UnMinimize );
|
||||||
minimized = false;
|
minimized = false;
|
||||||
if( isOnCurrentDesktop() && isShown( true ))
|
|
||||||
{
|
|
||||||
if( mainClients().isEmpty() && !avoid_animation )
|
|
||||||
animateMinimizeOrUnminimize( false );
|
|
||||||
}
|
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
updateAllowedActions();
|
updateAllowedActions();
|
||||||
workspace()->updateMinimizedOfTransients( this );
|
workspace()->updateMinimizedOfTransients( this );
|
||||||
updateWindowRules();
|
updateWindowRules();
|
||||||
if( effects )
|
if( effects && !avoid_animation )
|
||||||
effects->windowUnminimized( effectWindow());
|
effects->windowUnminimized( effectWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,130 +604,6 @@ QRect Client::iconGeometry() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool blockAnimation;
|
|
||||||
|
|
||||||
void Client::animateMinimizeOrUnminimize( bool minimize )
|
|
||||||
{
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#warning implement kwin animation
|
|
||||||
#endif
|
|
||||||
if ( 1 || blockAnimation )
|
|
||||||
return;
|
|
||||||
if ( !options->animateMinimize )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( decoration != NULL && decoration->animateMinimize( minimize ))
|
|
||||||
return; // decoration did it
|
|
||||||
|
|
||||||
// the function is a bit tricky since it will ensure that an
|
|
||||||
// animation action needs always the same time regardless of the
|
|
||||||
// performance of the machine or the X-Server.
|
|
||||||
|
|
||||||
float lf,rf,tf,bf,step;
|
|
||||||
|
|
||||||
int speed = options->animateMinimizeSpeed;
|
|
||||||
if ( speed > 10 )
|
|
||||||
speed = 10;
|
|
||||||
if ( speed < 0 )
|
|
||||||
speed = 0;
|
|
||||||
|
|
||||||
step = 40. * (11 - speed );
|
|
||||||
|
|
||||||
QRect icongeom = iconGeometry();
|
|
||||||
if ( !icongeom.isValid() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
QPixmap pm = animationPixmap( minimize ? width() : icongeom.width() );
|
|
||||||
|
|
||||||
QRect before, after;
|
|
||||||
if ( minimize )
|
|
||||||
{
|
|
||||||
before = QRect( x(), y(), width(), pm.height() );
|
|
||||||
after = QRect( icongeom.x(), icongeom.y(), icongeom.width(), pm.height() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
before = QRect( icongeom.x(), icongeom.y(), icongeom.width(), pm.height() );
|
|
||||||
after = QRect( x(), y(), width(), pm.height() );
|
|
||||||
}
|
|
||||||
|
|
||||||
lf = (after.left() - before.left())/step;
|
|
||||||
rf = (after.right() - before.right())/step;
|
|
||||||
tf = (after.top() - before.top())/step;
|
|
||||||
bf = (after.bottom() - before.bottom())/step;
|
|
||||||
|
|
||||||
grabXServer();
|
|
||||||
|
|
||||||
QRect area = before;
|
|
||||||
QRect area2;
|
|
||||||
QPixmap pm2;
|
|
||||||
|
|
||||||
QTime t;
|
|
||||||
t.start();
|
|
||||||
float diff;
|
|
||||||
|
|
||||||
QPainter p ( workspace()->desktopWidget() );
|
|
||||||
bool need_to_clear = false;
|
|
||||||
QPixmap pm3;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (area2 != area)
|
|
||||||
{
|
|
||||||
pm = animationPixmap( area.width() );
|
|
||||||
pm2 = QPixmap::grabWindow( rootWindow(), area.x(), area.y(), area.width(), area.height() );
|
|
||||||
p.drawPixmap( area.x(), area.y(), pm );
|
|
||||||
if ( need_to_clear )
|
|
||||||
{
|
|
||||||
p.drawPixmap( area2.x(), area2.y(), pm3 );
|
|
||||||
need_to_clear = false;
|
|
||||||
}
|
|
||||||
area2 = area;
|
|
||||||
}
|
|
||||||
XFlush(display());
|
|
||||||
XSync( display(), false );
|
|
||||||
diff = t.elapsed();
|
|
||||||
if (diff > step)
|
|
||||||
diff = step;
|
|
||||||
area.setLeft(before.left() + int(diff*lf));
|
|
||||||
area.setRight(before.right() + int(diff*rf));
|
|
||||||
area.setTop(before.top() + int(diff*tf));
|
|
||||||
area.setBottom(before.bottom() + int(diff*bf));
|
|
||||||
if (area2 != area )
|
|
||||||
{
|
|
||||||
if ( area2.intersects( area ) )
|
|
||||||
p.drawPixmap( area2.x(), area2.y(), pm2 );
|
|
||||||
else
|
|
||||||
{ // no overlap, we can clear later to avoid flicker
|
|
||||||
pm3 = pm2;
|
|
||||||
need_to_clear = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ( t.elapsed() < step);
|
|
||||||
if (area2 == area || need_to_clear )
|
|
||||||
p.drawPixmap( area2.x(), area2.y(), pm2 );
|
|
||||||
|
|
||||||
p.end();
|
|
||||||
ungrabXServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
The pixmap shown during (un)minimalization animation
|
|
||||||
*/
|
|
||||||
QPixmap Client::animationPixmap( int w )
|
|
||||||
{
|
|
||||||
QFont font = options->font(isActive());
|
|
||||||
QFontMetrics fm( font );
|
|
||||||
QPixmap pm( w, fm.lineSpacing() );
|
|
||||||
pm.fill( options->color(Options::ColorTitleBar, isActive() || isMinimized() ) );
|
|
||||||
QPainter p( &pm );
|
|
||||||
p.setPen(options->color(Options::ColorFont, isActive() || isMinimized() ));
|
|
||||||
p.setFont(options->font(isActive()));
|
|
||||||
p.drawText( pm.rect(), Qt::AlignLeft|Qt::AlignVCenter|Qt::TextSingleLine, caption() );
|
|
||||||
return pm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Client::isShadeable() const
|
bool Client::isShadeable() const
|
||||||
{
|
{
|
||||||
return !isSpecialWindow() && !noBorder();
|
return !isSpecialWindow() && !noBorder();
|
||||||
|
@ -775,13 +642,11 @@ void Client::setShade( ShadeMode mode )
|
||||||
// decorations may turn off some borders when shaded
|
// decorations may turn off some borders when shaded
|
||||||
decoration->borders( border_left, border_right, border_top, border_bottom );
|
decoration->borders( border_left, border_right, border_top, border_bottom );
|
||||||
|
|
||||||
int as = options->animateShade? 10 : 1;
|
|
||||||
// TODO all this unmapping, resizing etc. feels too much duplicated from elsewhere
|
// TODO all this unmapping, resizing etc. feels too much duplicated from elsewhere
|
||||||
if ( isShade())
|
if ( isShade())
|
||||||
{ // shade_mode == ShadeNormal
|
{ // shade_mode == ShadeNormal
|
||||||
workspace()->addRepaint( geometry());
|
workspace()->addRepaint( geometry());
|
||||||
// shade
|
// shade
|
||||||
int h = height();
|
|
||||||
shade_geometry_change = true;
|
shade_geometry_change = true;
|
||||||
QSize s( sizeForClientSize( QSize( clientSize())));
|
QSize s( sizeForClientSize( QSize( clientSize())));
|
||||||
s.setHeight( border_top + border_bottom );
|
s.setHeight( border_top + border_bottom );
|
||||||
|
@ -789,19 +654,6 @@ void Client::setShade( ShadeMode mode )
|
||||||
XUnmapWindow( display(), wrapper );
|
XUnmapWindow( display(), wrapper );
|
||||||
XUnmapWindow( display(), client );
|
XUnmapWindow( display(), client );
|
||||||
XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||||
// FRAME repaint( false );
|
|
||||||
// bool wasStaticContents = testWFlags( WStaticContents );
|
|
||||||
// setWFlags( WStaticContents );
|
|
||||||
int step = qMax( 4, QABS( h - s.height() ) / as )+1;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
h -= step;
|
|
||||||
XResizeWindow( display(), frameId(), s.width(), h );
|
|
||||||
resizeDecoration( QSize( s.width(), h ));
|
|
||||||
QApplication::syncX();
|
|
||||||
} while ( h > s.height() + step );
|
|
||||||
// if ( !wasStaticContents )
|
|
||||||
// clearWFlags( WStaticContents );
|
|
||||||
plainResize( s );
|
plainResize( s );
|
||||||
shade_geometry_change = false;
|
shade_geometry_change = false;
|
||||||
if( isActive())
|
if( isActive())
|
||||||
|
@ -814,24 +666,8 @@ void Client::setShade( ShadeMode mode )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int h = height();
|
|
||||||
shade_geometry_change = true;
|
shade_geometry_change = true;
|
||||||
QSize s( sizeForClientSize( clientSize()));
|
QSize s( sizeForClientSize( clientSize()));
|
||||||
// FRAME bool wasStaticContents = testWFlags( WStaticContents );
|
|
||||||
// setWFlags( WStaticContents );
|
|
||||||
int step = qMax( 4, QABS( h - s.height() ) / as )+1;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
h += step;
|
|
||||||
XResizeWindow( display(), frameId(), s.width(), h );
|
|
||||||
resizeDecoration( QSize( s.width(), h ));
|
|
||||||
// assume a border
|
|
||||||
// we do not have time to wait for X to send us paint events
|
|
||||||
// FRAME repaint( 0, h - step-5, width(), step+5, true);
|
|
||||||
QApplication::syncX();
|
|
||||||
} while ( h < s.height() - step );
|
|
||||||
// if ( !wasStaticContents )
|
|
||||||
// clearWFlags( WStaticContents );
|
|
||||||
shade_geometry_change = false;
|
shade_geometry_change = false;
|
||||||
plainResize( s );
|
plainResize( s );
|
||||||
if( shade_mode == ShadeHover || shade_mode == ShadeActivated )
|
if( shade_mode == ShadeHover || shade_mode == ShadeActivated )
|
||||||
|
|
2
client.h
2
client.h
|
@ -273,8 +273,6 @@ class Client
|
||||||
void setCursor( Position m );
|
void setCursor( Position m );
|
||||||
void setCursor( const QCursor& c );
|
void setCursor( const QCursor& c );
|
||||||
|
|
||||||
void animateMinimizeOrUnminimize( bool minimize );
|
|
||||||
QPixmap animationPixmap( int w );
|
|
||||||
// transparent stuff
|
// transparent stuff
|
||||||
void drawbound( const QRect& geom );
|
void drawbound( const QRect& geom );
|
||||||
void clearbound();
|
void clearbound();
|
||||||
|
|
282
events.cpp
282
events.cpp
|
@ -21,6 +21,9 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
#include "tabbox.h"
|
#include "tabbox.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
|
#include "unmanaged.h"
|
||||||
|
#include "scene.h"
|
||||||
|
#include "effects.h"
|
||||||
|
|
||||||
#include <QWhatsThis>
|
#include <QWhatsThis>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
@ -83,6 +86,10 @@ void WinInfo::changeState( unsigned long state, unsigned long mask )
|
||||||
m_client->setFullScreen( true, false );
|
m_client->setFullScreen( true, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WinInfo::disable()
|
||||||
|
{
|
||||||
|
m_client = NULL; // only used when the object is passed to Deleted
|
||||||
|
}
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
// RootInfo
|
// RootInfo
|
||||||
|
@ -199,15 +206,10 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
XUngrabKeyboard( display(), xTime() );
|
XUngrabKeyboard( display(), xTime() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( e->type == PropertyNotify || e->type == ClientMessage )
|
if ( e->type == PropertyNotify || e->type == ClientMessage )
|
||||||
{
|
{
|
||||||
unsigned long dirty[ NETRootInfo::PROPERTIES_SIZE ];
|
if ( netCheck( e ) )
|
||||||
rootInfo->event( e, dirty, NETRootInfo::PROPERTIES_SIZE );
|
return true;
|
||||||
if( dirty[ NETRootInfo::PROTOCOLS ] & NET::DesktopNames )
|
|
||||||
saveDesktopSettings();
|
|
||||||
if( dirty[ NETRootInfo::PROTOCOLS2 ] & NET::WM2DesktopLayout )
|
|
||||||
setDesktopLayout( rootInfo->desktopLayoutOrientation(), rootInfo->desktopLayoutColumnsRows().width(),
|
|
||||||
rootInfo->desktopLayoutColumnsRows().height(), rootInfo->desktopLayoutCorner());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// events that should be handled before Clients can get them
|
// events that should be handled before Clients can get them
|
||||||
|
@ -223,6 +225,8 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
tab_box->handleMouseEvent( e );
|
tab_box->handleMouseEvent( e );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if( effects && effects->checkInputWindowEvent( e ))
|
||||||
|
return true;
|
||||||
break;
|
break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
{
|
||||||
|
@ -267,6 +271,11 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
if( c->windowEvent( e ))
|
if( c->windowEvent( e ))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if( Unmanaged* c = findUnmanaged( WindowMatchPredicate( e->xany.window )))
|
||||||
|
{
|
||||||
|
if( c->windowEvent( e ))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Window special = findSpecialEventWindow( e );
|
Window special = findSpecialEventWindow( e );
|
||||||
|
@ -324,13 +333,8 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt
|
return ( e->xunmap.event != e->xunmap.window ); // hide wm typical event from Qt
|
||||||
}
|
}
|
||||||
case MapNotify:
|
|
||||||
|
|
||||||
return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt
|
|
||||||
|
|
||||||
case ReparentNotify:
|
case ReparentNotify:
|
||||||
{
|
{
|
||||||
//do not confuse Qt with these events. After all, _we_ are the
|
//do not confuse Qt with these events. After all, _we_ are the
|
||||||
|
@ -380,6 +384,19 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MapNotify:
|
||||||
|
{
|
||||||
|
if( e->xmap.override_redirect )
|
||||||
|
{
|
||||||
|
Unmanaged* c = findUnmanaged( WindowMatchPredicate( e->xmap.window ));
|
||||||
|
if( c == NULL )
|
||||||
|
c = createUnmanaged( e->xmap.window );
|
||||||
|
if( c )
|
||||||
|
return c->windowEvent( e );
|
||||||
|
}
|
||||||
|
return ( e->xmap.event != e->xmap.window ); // hide wm typical event from Qt
|
||||||
|
}
|
||||||
|
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
{
|
{
|
||||||
if ( QWhatsThis::inWhatsThisMode() )
|
if ( QWhatsThis::inWhatsThisMode() )
|
||||||
|
@ -456,7 +473,29 @@ bool Workspace::workspaceEvent( XEvent * e )
|
||||||
if( electricBorder( e ))
|
if( electricBorder( e ))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
case MappingNotify:
|
||||||
|
XRefreshKeyboardMapping( &e->xmapping );
|
||||||
|
tab_box->updateKeyMapping();
|
||||||
|
break;
|
||||||
|
case Expose:
|
||||||
|
if( e->xexpose.window == rootWindow() && compositing()) // root window needs repainting
|
||||||
|
addRepaint( e->xexpose.x, e->xexpose.y, e->xexpose.width, e->xexpose.height );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
if( e->type == Extensions::randrNotifyEvent() && Extensions::randrAvailable() )
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XRANDR
|
||||||
|
XRRUpdateConfiguration( e );
|
||||||
|
#endif
|
||||||
|
if( compositing() )
|
||||||
|
{
|
||||||
|
// desktopResized() should take care of when the size or
|
||||||
|
// shape of the desktop has changed, but we also want to
|
||||||
|
// catch refresh rate changes
|
||||||
|
finishCompositing();
|
||||||
|
QTimer::singleShot( 0, this, SLOT( setupCompositing() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -496,6 +535,20 @@ Window Workspace::findSpecialEventWindow( XEvent* e )
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Handles client messages sent to the workspace
|
||||||
|
*/
|
||||||
|
bool Workspace::netCheck( XEvent* e )
|
||||||
|
{
|
||||||
|
unsigned int dirty = rootInfo->event( e );
|
||||||
|
|
||||||
|
if ( dirty & NET::DesktopNames )
|
||||||
|
saveDesktopSettings();
|
||||||
|
|
||||||
|
return dirty != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
// Client
|
// Client
|
||||||
// ****************************************
|
// ****************************************
|
||||||
|
@ -508,6 +561,7 @@ bool Client::windowEvent( XEvent* e )
|
||||||
if( e->xany.window == window()) // avoid doing stuff on frame or wrapper
|
if( e->xany.window == window()) // avoid doing stuff on frame or wrapper
|
||||||
{
|
{
|
||||||
unsigned long dirty[ 2 ];
|
unsigned long dirty[ 2 ];
|
||||||
|
double old_opacity = opacity();
|
||||||
info->event( e, dirty, 2 ); // pass through the NET stuff
|
info->event( e, dirty, 2 ); // pass through the NET stuff
|
||||||
|
|
||||||
if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMName ) != 0 )
|
if ( ( dirty[ WinInfo::PROTOCOLS ] & NET::WMName ) != 0 )
|
||||||
|
@ -538,6 +592,21 @@ bool Client::windowEvent( XEvent* e )
|
||||||
if( demandAttentionKNotifyTimer != NULL )
|
if( demandAttentionKNotifyTimer != NULL )
|
||||||
demandAttentionKNotify();
|
demandAttentionKNotify();
|
||||||
}
|
}
|
||||||
|
if( dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
|
||||||
|
{
|
||||||
|
if( compositing())
|
||||||
|
{
|
||||||
|
addRepaintFull();
|
||||||
|
scene->windowOpacityChanged( this );
|
||||||
|
if( effects )
|
||||||
|
effects->windowOpacityChanged( effectWindow(), old_opacity );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // forward to the frame if there's possibly another compositing manager running
|
||||||
|
NETWinInfo i( display(), frameId(), rootWindow(), 0 );
|
||||||
|
i.setOpacity( info->opacity());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO move all focus handling stuff to separate file?
|
// TODO move all focus handling stuff to separate file?
|
||||||
|
@ -618,15 +687,23 @@ bool Client::windowEvent( XEvent* e )
|
||||||
workspace()->updateColormap();
|
workspace()->updateColormap();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VisibilityNotify:
|
||||||
|
visibilityNotifyEvent( &e->xvisibility );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if( e->xany.window == window())
|
if( e->xany.window == window())
|
||||||
{
|
|
||||||
if( e->type == Shape::shapeEvent() )
|
|
||||||
{
|
{
|
||||||
is_shape = Shape::hasShape( window()); // workaround for #19644
|
if( e->type == Extensions::shapeNotifyEvent() )
|
||||||
updateShape();
|
{
|
||||||
|
detectShape( window()); // workaround for #19644
|
||||||
|
updateShape();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( e->xany.window == frameId())
|
||||||
|
{
|
||||||
|
if( e->type == Extensions::damageNotifyEvent())
|
||||||
|
damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e ));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true; // eat all events
|
return true; // eat all events
|
||||||
|
@ -728,8 +805,6 @@ void Client::destroyNotifyEvent( XDestroyWindowEvent* e )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool blockAnimation = false;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Handles client messages for the client window
|
Handles client messages for the client window
|
||||||
*/
|
*/
|
||||||
|
@ -742,14 +817,13 @@ void Client::clientMessageEvent( XClientMessageEvent* e )
|
||||||
{
|
{
|
||||||
if( isTopMenu() && workspace()->managingTopMenus())
|
if( isTopMenu() && workspace()->managingTopMenus())
|
||||||
return; // kwin controls these
|
return; // kwin controls these
|
||||||
if( e->data.l[ 1 ] )
|
bool avoid_animation = ( e->data.l[ 1 ] );
|
||||||
blockAnimation = true;
|
|
||||||
if( e->data.l[ 0 ] == IconicState )
|
if( e->data.l[ 0 ] == IconicState )
|
||||||
minimize();
|
minimize();
|
||||||
else if( e->data.l[ 0 ] == NormalState )
|
else if( e->data.l[ 0 ] == NormalState )
|
||||||
{ // copied from mapRequest()
|
{ // copied from mapRequest()
|
||||||
if( isMinimized())
|
if( isMinimized())
|
||||||
unminimize();
|
unminimize( avoid_animation );
|
||||||
if( isShade())
|
if( isShade())
|
||||||
setShade( ShadeNone );
|
setShade( ShadeNone );
|
||||||
if( !isOnCurrentDesktop())
|
if( !isOnCurrentDesktop())
|
||||||
|
@ -760,7 +834,6 @@ void Client::clientMessageEvent( XClientMessageEvent* e )
|
||||||
demandAttention();
|
demandAttention();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blockAnimation = false;
|
|
||||||
}
|
}
|
||||||
else if ( e->message_type == atoms->wm_change_state)
|
else if ( e->message_type == atoms->wm_change_state)
|
||||||
{
|
{
|
||||||
|
@ -829,6 +902,7 @@ void Client::configureRequestEvent( XConfigureRequestEvent* e )
|
||||||
*/
|
*/
|
||||||
void Client::propertyNotifyEvent( XPropertyEvent* e )
|
void Client::propertyNotifyEvent( XPropertyEvent* e )
|
||||||
{
|
{
|
||||||
|
Toplevel::propertyNotifyEvent( e );
|
||||||
if( e->window != window())
|
if( e->window != window())
|
||||||
return; // ignore frame/wrapper
|
return; // ignore frame/wrapper
|
||||||
switch ( e->atom )
|
switch ( e->atom )
|
||||||
|
@ -852,10 +926,6 @@ void Client::propertyNotifyEvent( XPropertyEvent* e )
|
||||||
default:
|
default:
|
||||||
if ( e->atom == atoms->wm_protocols )
|
if ( e->atom == atoms->wm_protocols )
|
||||||
getWindowProtocols();
|
getWindowProtocols();
|
||||||
else if (e->atom == atoms->wm_client_leader )
|
|
||||||
getWmClientLeader();
|
|
||||||
else if( e->atom == atoms->wm_window_role )
|
|
||||||
window_role = staticWindowRole( window());
|
|
||||||
else if( e->atom == atoms->motif_wm_hints )
|
else if( e->atom == atoms->motif_wm_hints )
|
||||||
getMotifHints();
|
getMotifHints();
|
||||||
break;
|
break;
|
||||||
|
@ -995,13 +1065,18 @@ void Client::ungrabButton( int modifier )
|
||||||
*/
|
*/
|
||||||
void Client::updateMouseGrab()
|
void Client::updateMouseGrab()
|
||||||
{
|
{
|
||||||
|
if( workspace()->globalShortcutsDisabled())
|
||||||
|
{
|
||||||
|
XUngrabButton( display(), AnyButton, AnyModifier, wrapperId());
|
||||||
|
// keep grab for the simple click without modifiers if needed
|
||||||
|
if( !( !options->clickRaise || not_obscured ))
|
||||||
|
grabButton( None );
|
||||||
|
return;
|
||||||
|
}
|
||||||
if( isActive() && !workspace()->forcedGlobalMouseGrab()) // see Workspace::establishTabBoxGrab()
|
if( isActive() && !workspace()->forcedGlobalMouseGrab()) // see Workspace::establishTabBoxGrab()
|
||||||
{
|
{
|
||||||
// remove the grab for no modifiers only if the window
|
// remove the grab for no modifiers only if the window
|
||||||
// is unobscured or if the user doesn't want click raise
|
// is unobscured or if the user doesn't want click raise
|
||||||
// (it is unobscured if it the topmost in the unconstrained stacking order, i.e. it is
|
|
||||||
// the most recently raised window)
|
|
||||||
bool not_obscured = workspace()->topClientOnDesktop( workspace()->currentDesktop(), true, false ) == this;
|
|
||||||
if( !options->clickRaise || not_obscured )
|
if( !options->clickRaise || not_obscured )
|
||||||
ungrabButton( None );
|
ungrabButton( None );
|
||||||
else
|
else
|
||||||
|
@ -1021,37 +1096,6 @@ void Client::updateMouseGrab()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int qtToX11Button( Qt::ButtonState button )
|
|
||||||
{
|
|
||||||
if( button == Qt::LeftButton )
|
|
||||||
return Button1;
|
|
||||||
else if( button == Qt::MidButton )
|
|
||||||
return Button2;
|
|
||||||
else if( button == Qt::RightButton )
|
|
||||||
return Button3;
|
|
||||||
return AnyButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
int qtToX11State( Qt::ButtonState buttons, Qt::KeyboardModifiers modifiers )
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
if( buttons & Qt::LeftButton )
|
|
||||||
ret |= Button1Mask;
|
|
||||||
if( buttons & Qt::MidButton )
|
|
||||||
ret |= Button2Mask;
|
|
||||||
if( buttons & Qt::RightButton )
|
|
||||||
ret |= Button3Mask;
|
|
||||||
if( modifiers & Qt::ShiftModifier )
|
|
||||||
ret |= ShiftMask;
|
|
||||||
if( modifiers & Qt::ControlModifier )
|
|
||||||
ret |= ControlMask;
|
|
||||||
if( modifiers & Qt::AltModifier )
|
|
||||||
ret |= KKeyServer::modXAlt();
|
|
||||||
if( modifiers & Qt::MetaModifier )
|
|
||||||
ret |= KKeyServer::modXMeta();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Qt propagates mouse events up the widget hierachy, which means events
|
// Qt propagates mouse events up the widget hierachy, which means events
|
||||||
// for the decoration window cannot be (easily) intercepted as X11 events
|
// for the decoration window cannot be (easily) intercepted as X11 events
|
||||||
bool Client::eventFilter( QObject* o, QEvent* e )
|
bool Client::eventFilter( QObject* o, QEvent* e )
|
||||||
|
@ -1095,6 +1139,15 @@ bool Client::eventFilter( QObject* o, QEvent* e )
|
||||||
// on the decoration widget.
|
// on the decoration widget.
|
||||||
if( ev->size() != size())
|
if( ev->size() != size())
|
||||||
return true;
|
return true;
|
||||||
|
// HACK: Avoid decoration redraw delays. On resize Qt sets WA_WStateConfigPending
|
||||||
|
// which delays all painting until a matching ConfigureNotify event comes.
|
||||||
|
// But this process itself is the window manager, so it's not needed
|
||||||
|
// to wait for that event, the geometry is known.
|
||||||
|
// Note that if Qt in the future changes how this flag is handled and what it
|
||||||
|
// triggers then this may potentionally break things. See mainly QETWidget::translateConfigEvent().
|
||||||
|
decoration->widget()->setAttribute( Qt::WA_WState_ConfigPending, false );
|
||||||
|
decoration->widget()->update();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1436,6 +1489,17 @@ void Client::focusOutEvent( XFocusOutEvent* e )
|
||||||
setActive( false );
|
setActive( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::visibilityNotifyEvent( XVisibilityEvent * e)
|
||||||
|
{
|
||||||
|
if( e->window != frameId())
|
||||||
|
return; // care only about the whole frame
|
||||||
|
bool new_not_obscured = e->state == VisibilityUnobscured;
|
||||||
|
if( not_obscured == new_not_obscured )
|
||||||
|
return;
|
||||||
|
not_obscured = new_not_obscured;
|
||||||
|
updateMouseGrab();
|
||||||
|
}
|
||||||
|
|
||||||
// performs _NET_WM_MOVERESIZE
|
// performs _NET_WM_MOVERESIZE
|
||||||
void Client::NETMoveResize( int x_root, int y_root, NET::Direction direction )
|
void Client::NETMoveResize( int x_root, int y_root, NET::Direction direction )
|
||||||
{
|
{
|
||||||
|
@ -1497,7 +1561,7 @@ void Client::keyPressEvent( uint key_code )
|
||||||
bool is_alt = key_code & Qt::ALT;
|
bool is_alt = key_code & Qt::ALT;
|
||||||
key_code = key_code & 0xffff;
|
key_code = key_code & 0xffff;
|
||||||
int delta = is_control?1:is_alt?32:8;
|
int delta = is_control?1:is_alt?32:8;
|
||||||
QPoint pos = QCursor::pos();
|
QPoint pos = cursorPos();
|
||||||
switch ( key_code )
|
switch ( key_code )
|
||||||
{
|
{
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Left:
|
||||||
|
@ -1530,6 +1594,98 @@ void Client::keyPressEvent( uint key_code )
|
||||||
QCursor::setPos( pos );
|
QCursor::setPos( pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ****************************************
|
||||||
|
// Unmanaged
|
||||||
|
// ****************************************
|
||||||
|
|
||||||
|
bool Unmanaged::windowEvent( XEvent* e )
|
||||||
|
{
|
||||||
|
double old_opacity = opacity();
|
||||||
|
unsigned long dirty[ 2 ];
|
||||||
|
info->event( e, dirty, 2 ); // pass through the NET stuff
|
||||||
|
if( dirty[ NETWinInfo::PROTOCOLS2 ] & NET::WM2Opacity )
|
||||||
|
{
|
||||||
|
if( compositing())
|
||||||
|
{
|
||||||
|
addRepaintFull();
|
||||||
|
scene->windowOpacityChanged( this );
|
||||||
|
if( effects )
|
||||||
|
effects->windowOpacityChanged( effectWindow(), old_opacity );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (e->type)
|
||||||
|
{
|
||||||
|
case UnmapNotify:
|
||||||
|
unmapNotifyEvent( &e->xunmap );
|
||||||
|
break;
|
||||||
|
case MapNotify:
|
||||||
|
mapNotifyEvent( &e->xmap );
|
||||||
|
break;
|
||||||
|
case ConfigureNotify:
|
||||||
|
configureNotifyEvent( &e->xconfigure );
|
||||||
|
break;
|
||||||
|
case PropertyNotify:
|
||||||
|
propertyNotifyEvent( &e->xproperty );
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if( e->type == Extensions::shapeNotifyEvent() )
|
||||||
|
{
|
||||||
|
detectShape( window());
|
||||||
|
if( compositing() )
|
||||||
|
discardWindowPixmap();
|
||||||
|
if( scene != NULL )
|
||||||
|
scene->windowGeometryShapeChanged( this );
|
||||||
|
}
|
||||||
|
if( e->type == Extensions::damageNotifyEvent())
|
||||||
|
damageNotifyEvent( reinterpret_cast< XDamageNotifyEvent* >( e ));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // don't eat events, even our own unmanaged widgets are tracked
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unmanaged::mapNotifyEvent( XMapEvent* )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unmanaged::unmapNotifyEvent( XUnmapEvent* )
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unmanaged::configureNotifyEvent( XConfigureEvent* e )
|
||||||
|
{
|
||||||
|
if( effects )
|
||||||
|
effects->checkInputWindowStacking(); // keep them on top
|
||||||
|
QRect newgeom( e->x, e->y, e->width, e->height );
|
||||||
|
if( newgeom == geom )
|
||||||
|
return;
|
||||||
|
workspace()->addRepaint( geometry()); // damage old area
|
||||||
|
geom = newgeom;
|
||||||
|
if( scene != NULL )
|
||||||
|
scene->windowGeometryShapeChanged( this );
|
||||||
|
discardWindowPixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ****************************************
|
||||||
|
// Toplevel
|
||||||
|
// ****************************************
|
||||||
|
|
||||||
|
void Toplevel::propertyNotifyEvent( XPropertyEvent* e )
|
||||||
|
{
|
||||||
|
if( e->window != window())
|
||||||
|
return; // ignore frame/wrapper
|
||||||
|
switch ( e->atom )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
if (e->atom == atoms->wm_client_leader )
|
||||||
|
getWmClientLeader();
|
||||||
|
else if( e->atom == atoms->wm_window_role )
|
||||||
|
getWindowRole();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ****************************************
|
// ****************************************
|
||||||
// Group
|
// Group
|
||||||
// ****************************************
|
// ****************************************
|
||||||
|
|
Loading…
Reference in New Issue