Merge r608181 from trunk (KShortcut/KAction changes).

svn path=/branches/work/kwin_composite/; revision=610146
This commit is contained in:
Luboš Luňák 2006-12-03 13:43:37 +00:00
parent 4607cab829
commit 840364cd2a
5 changed files with 187 additions and 351 deletions

View file

@ -28,6 +28,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include "atoms.h" #include "atoms.h"
#include "notifications.h" #include "notifications.h"
#include "rules.h" #include "rules.h"
#include "scene.h"
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#include <QX11Info> #include <QX11Info>
@ -63,12 +64,10 @@ namespace KWinInternal
is done in manage(). is done in manage().
*/ */
Client::Client( Workspace *ws ) Client::Client( Workspace *ws )
: QObject( NULL ), : Toplevel( ws ),
client( None ), client( None ),
wrapper( None ), wrapper( None ),
frame( None ),
decoration( NULL ), decoration( NULL ),
wspace( ws ),
bridge( new Bridge( this )), bridge( new Bridge( this )),
move_faked_activity( false ), move_faked_activity( false ),
move_resize_grab_window( None ), move_resize_grab_window( None ),
@ -82,7 +81,7 @@ Client::Client( Workspace *ws )
process_killer( NULL ), process_killer( NULL ),
user_time( CurrentTime ), // not known yet user_time( CurrentTime ), // not known yet
allowed_actions( 0 ), allowed_actions( 0 ),
postpone_geometry_updates( 0 ), block_geometry_updates( 0 ),
pending_geometry_update( false ), pending_geometry_update( false ),
shade_geometry_change( false ), shade_geometry_change( false ),
border_left( 0 ), border_left( 0 ),
@ -111,7 +110,6 @@ Client::Client( Workspace *ws )
deleting = false; deleting = false;
keep_above = false; keep_above = false;
keep_below = false; keep_below = false;
is_shape = false;
motif_noborder = false; motif_noborder = false;
motif_may_move = true; motif_may_move = true;
motif_may_resize = true; motif_may_resize = true;
@ -124,6 +122,7 @@ Client::Client( Workspace *ws )
modal = false; modal = false;
noborder = false; noborder = false;
user_noborder = false; user_noborder = false;
not_obscured = false;
urgency = false; urgency = false;
ignore_focus_stealing = false; ignore_focus_stealing = false;
demands_attention = false; demands_attention = false;
@ -142,7 +141,7 @@ Client::Client( Workspace *ws )
cmap = None; cmap = None;
frame_geometry = QRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0) geom = QRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0)
client_size = QSize( 100, 100 ); client_size = QSize( 100, 100 );
// SELI initialize xsizehints?? // SELI initialize xsizehints??
@ -155,9 +154,10 @@ Client::~Client()
{ {
assert(!moveResizeMode); assert(!moveResizeMode);
assert( client == None ); assert( client == None );
assert( frame == None && wrapper == None ); assert( wrapper == None );
// assert( frameId() == None );
assert( decoration == NULL ); assert( decoration == NULL );
assert( postpone_geometry_updates == 0 ); assert( block_geometry_updates == 0 );
assert( !check_active_modal ); assert( !check_active_modal );
delete info; delete info;
delete bridge; delete bridge;
@ -176,15 +176,15 @@ void Client::releaseWindow( bool on_shutdown )
{ {
assert( !deleting ); assert( !deleting );
deleting = true; deleting = true;
finishCompositing();
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
StackingUpdatesBlocker blocker( workspace()); StackingUpdatesBlocker blocker( workspace());
if (moveResizeMode) if (moveResizeMode)
leaveMoveResize(); leaveMoveResize();
finishWindowRules(); finishWindowRules();
++postpone_geometry_updates; ++block_geometry_updates;
// grab X during the release to make removing of properties, setting to withdrawn state if( isNormalState()) // is mapped?
// and repareting to root an atomic operation (http://lists.kde.org/?l=kde-devel&m=116448102901184&w=2) workspace()->addDamage( geometry());
grabXServer();
setMappingState( WithdrawnState ); setMappingState( WithdrawnState );
setModal( false ); // otherwise its mainwindow wouldn't get focus setModal( false ); // otherwise its mainwindow wouldn't get focus
hidden = true; // so that it's not considered visible anymore (can't use hideClient(), it would set flags) hidden = true; // so that it's not considered visible anymore (can't use hideClient(), it would set flags)
@ -222,11 +222,10 @@ void Client::releaseWindow( bool on_shutdown )
client = None; client = None;
XDestroyWindow( display(), wrapper ); XDestroyWindow( display(), wrapper );
wrapper = None; wrapper = None;
XDestroyWindow( display(), frame ); XDestroyWindow( display(), frameId());
frame = None; // frame = None;
--postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry --block_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
deleteClient( this, Allowed ); deleteClient( this, Allowed );
ungrabXServer();
} }
// like releaseWindow(), but this one is called when the window has been already destroyed // like releaseWindow(), but this one is called when the window has been already destroyed
@ -235,12 +234,15 @@ void Client::destroyClient()
{ {
assert( !deleting ); assert( !deleting );
deleting = true; deleting = true;
finishCompositing();
workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules workspace()->discardUsedWindowRules( this, true ); // remove ForceTemporarily rules
StackingUpdatesBlocker blocker( workspace()); StackingUpdatesBlocker blocker( workspace());
if (moveResizeMode) if (moveResizeMode)
leaveMoveResize(); leaveMoveResize();
finishWindowRules(); finishWindowRules();
++postpone_geometry_updates; ++block_geometry_updates;
if( isNormalState()) // is mapped?
workspace()->addDamage( geometry());
setModal( false ); setModal( false );
hidden = true; // so that it's not considered visible anymore hidden = true; // so that it's not considered visible anymore
workspace()->clientHidden( this ); workspace()->clientHidden( this );
@ -250,9 +252,9 @@ void Client::destroyClient()
client = None; // invalidate client = None; // invalidate
XDestroyWindow( display(), wrapper ); XDestroyWindow( display(), wrapper );
wrapper = None; wrapper = None;
XDestroyWindow( display(), frame ); XDestroyWindow( display(), frameId());
frame = None; // frame = None;
--postpone_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry --block_geometry_updates; // don't use GeometryUpdatesBlocker, it would now set the geometry
deleteClient( this, Allowed ); deleteClient( this, Allowed );
} }
@ -262,12 +264,11 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
|| ( decoration != NULL && !noBorder()))) || ( decoration != NULL && !noBorder())))
return; return;
bool do_show = false; bool do_show = false;
postponeGeometryUpdates( true ); blockGeometryUpdates( true );
if( force ) if( force )
destroyDecoration(); destroyDecoration();
if( !noBorder()) if( !noBorder())
{ {
setMask( QRegion()); // reset shape mask
decoration = workspace()->createDecoration( bridge ); decoration = workspace()->createDecoration( bridge );
// TODO check decoration's minimum size? // TODO check decoration's minimum size?
decoration->init(); decoration->init();
@ -282,15 +283,18 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
workarea_diff_x = save_workarea_diff_x; workarea_diff_x = save_workarea_diff_x;
workarea_diff_y = save_workarea_diff_y; workarea_diff_y = save_workarea_diff_y;
do_show = true; do_show = true;
if( scene != NULL )
scene->windowGeometryShapeChanged( this );
} }
else else
destroyDecoration(); destroyDecoration();
if( check_workspace_pos ) if( check_workspace_pos )
checkWorkspacePosition(); checkWorkspacePosition();
postponeGeometryUpdates( false ); blockGeometryUpdates( false );
if( do_show ) if( do_show )
decoration->widget()->show(); decoration->widget()->show();
updateFrameExtents(); updateFrameExtents();
addDamageFull();
} }
void Client::destroyDecoration() void Client::destroyDecoration()
@ -308,6 +312,9 @@ void Client::destroyDecoration()
move( grav ); move( grav );
workarea_diff_x = save_workarea_diff_x; workarea_diff_x = save_workarea_diff_x;
workarea_diff_y = save_workarea_diff_y; workarea_diff_y = save_workarea_diff_y;
if( scene != NULL )
scene->windowGeometryShapeChanged( this );
addDamageFull();
} }
} }
@ -320,7 +327,7 @@ void Client::checkBorderSizes()
if( new_left == border_left && new_right == border_right if( new_left == border_left && new_right == border_right
&& new_top == border_top && new_bottom == border_bottom ) && new_top == border_top && new_bottom == border_bottom )
return; return;
GeometryUpdatesPostponer blocker( this ); GeometryUpdatesBlocker blocker( this );
move( calculateGravitation( true )); move( calculateGravitation( true ));
border_left = new_left; border_left = new_left;
border_right = new_right; border_right = new_right;
@ -337,7 +344,7 @@ void Client::checkBorderSizes()
void Client::detectNoBorder() void Client::detectNoBorder()
{ {
if( Shape::hasShape( window())) if( shape())
{ {
noborder = true; noborder = true;
return; return;
@ -425,47 +432,22 @@ void Client::setUserNoBorder( bool set )
void Client::updateShape() void Client::updateShape()
{ {
if ( shape() )
XShapeCombineShape(display(), frameId(), ShapeBounding,
clientPos().x(), clientPos().y(),
window(), ShapeBounding, ShapeSet);
else
XShapeCombineMask( display(), frameId(), ShapeBounding, 0, 0,
None, ShapeSet);
if( scene != NULL )
scene->windowGeometryShapeChanged( this );
addDamageFull();
// workaround for #19644 - shaped windows shouldn't have decoration // workaround for #19644 - shaped windows shouldn't have decoration
if( shape() && !noBorder()) if( shape() && !noBorder())
{ {
noborder = true; noborder = true;
updateDecoration( true ); updateDecoration( true );
} }
if( shape())
{
XShapeCombineShape(display(), frameId(), ShapeBounding,
clientPos().x(), clientPos().y(),
window(), ShapeBounding, ShapeSet);
}
// !shape() mask setting is done in setMask() when the decoration
// calls it or when the decoration is created/destroyed
if( Shape::version() >= 0x11 ) // 1.1, has input shape support
{ // There appears to be no way to find out if a window has input
// shape set or not, so always propagate the input shape
// (it's the same like the bounding shape by default).
// Also, build the shape using a helper window, not directly
// in the frame window, because the sequence set-shape-to-frame,
// remove-shape-of-client, add-input-shape-of-client has the problem
// that after the second step there's a hole in the input shape
// until the real shape of the client is added and that can make
// the window lose focus (which is a problem with mouse focus policies)
static Window helper_window = None;
if( helper_window == None )
helper_window = XCreateSimpleWindow( display(), rootWindow(),
0, 0, 1, 1, 0, 0, 0 );
XResizeWindow( display(), helper_window, width(), height());
XShapeCombineShape( display(), helper_window, ShapeInput, 0, 0,
frameId(), ShapeBounding, ShapeSet );
XShapeCombineShape( display(), helper_window, ShapeInput,
clientPos().x(), clientPos().y(),
window(), ShapeBounding, ShapeSubtract );
XShapeCombineShape( display(), helper_window, ShapeInput,
clientPos().x(), clientPos().y(),
window(), ShapeInput, ShapeUnion );
XShapeCombineShape( display(), frameId(), ShapeInput, 0, 0,
helper_window, ShapeInput, ShapeSet );
}
} }
void Client::setMask( const QRegion& reg, int mode ) void Client::setMask( const QRegion& reg, int mode )
@ -494,7 +476,9 @@ void Client::setMask( const QRegion& reg, int mode )
xrects, rects.count(), ShapeSet, mode ); xrects, rects.count(), ShapeSet, mode );
delete[] xrects; delete[] xrects;
} }
updateShape(); if( scene != NULL )
scene->windowGeometryShapeChanged( this );
addDamageFull();
} }
QRegion Client::mask() const QRegion Client::mask() const
@ -743,7 +727,7 @@ void Client::setShade( ShadeMode mode )
} }
assert( decoration != NULL ); // noborder windows can't be shaded assert( decoration != NULL ); // noborder windows can't be shaded
GeometryUpdatesPostponer blocker( this ); GeometryUpdatesBlocker blocker( this );
// 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 );
@ -790,9 +774,13 @@ void Client::setShade( ShadeMode mode )
// tell xcompmgr shade's done // tell xcompmgr shade's done
_shade = 2; _shade = 2;
XChangeProperty(display(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L); XChangeProperty(display(), frameId(), atoms->net_wm_window_shade, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &_shade, 1L);
if( isNormalState()) // is mapped?
workspace()->addDamage( geometry());
} }
else else
{ {
if( isNormalState()) // is mapped?
workspace()->addDamage( geometry());
int h = height(); int h = height();
shade_geometry_change = true; shade_geometry_change = true;
QSize s( sizeForClientSize( clientSize())); QSize s( sizeForClientSize( clientSize()));
@ -927,8 +915,8 @@ void Client::setMappingState(int s)
XChangeProperty(display(), window(), atoms->wm_state, atoms->wm_state, 32, XChangeProperty(display(), window(), atoms->wm_state, atoms->wm_state, 32,
PropModeReplace, (unsigned char *)data, 2); PropModeReplace, (unsigned char *)data, 2);
if( was_unmanaged ) // manage() did postpone_geometry_updates = 1, now it's ok to finally set the geometry if( was_unmanaged ) // manage() did block_geometry_updates = 1, now it's ok to finally set the geometry
postponeGeometryUpdates( false ); blockGeometryUpdates( false );
} }
/*! /*!
@ -939,7 +927,7 @@ void Client::rawShow()
{ {
if( decoration != NULL ) if( decoration != NULL )
decoration->widget()->show(); // not really necessary, but let it know the state decoration->widget()->show(); // not really necessary, but let it know the state
XMapWindow( display(), frame ); XMapWindow( display(), frameId());
if( !isShade()) if( !isShade())
{ {
XMapWindow( display(), wrapper ); XMapWindow( display(), wrapper );
@ -954,6 +942,7 @@ void Client::rawShow()
*/ */
void Client::rawHide() void Client::rawHide()
{ {
workspace()->addDamage( geometry());
// Here it may look like a race condition, as some other client might try to unmap // Here it may look like a race condition, as some other client might try to unmap
// the window between these two XSelectInput() calls. However, they're supposed to // the window between these two XSelectInput() calls. However, they're supposed to
// use XWithdrawWindow(), which also sends a synthetic event to the root window, // use XWithdrawWindow(), which also sends a synthetic event to the root window,
@ -961,7 +950,7 @@ void Client::rawHide()
// will be missed is also very minimal, so I don't think it's needed to grab the server // will be missed is also very minimal, so I don't think it's needed to grab the server
// here. // here.
XSelectInput( display(), wrapper, ClientWinMask ); // avoid getting UnmapNotify XSelectInput( display(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
XUnmapWindow( display(), frame ); XUnmapWindow( display(), frameId());
XUnmapWindow( display(), wrapper ); XUnmapWindow( display(), wrapper );
XUnmapWindow( display(), client ); XUnmapWindow( display(), client );
XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask ); XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
@ -1306,7 +1295,7 @@ QString Client::readName() const
return KWin::readNameProperty( window(), XA_WM_NAME ); return KWin::readNameProperty( window(), XA_WM_NAME );
} }
KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption()); KWIN_COMPARE_PREDICATE( FetchNameInternalPredicate, Client, const Client*, (!cl->isSpecialWindow() || cl->isToolbar()) && cl != value && cl->caption() == value->caption());
void Client::setCaption( const QString& _s, bool force ) void Client::setCaption( const QString& _s, bool force )
{ {
@ -1623,58 +1612,6 @@ bool Client::wantsInput() const
return rules()->checkAcceptFocus( input || Ptakefocus ); return rules()->checkAcceptFocus( input || Ptakefocus );
} }
bool Client::isDesktop() const
{
return windowType() == NET::Desktop;
}
bool Client::isDock() const
{
return windowType() == NET::Dock;
}
bool Client::isTopMenu() const
{
return windowType() == NET::TopMenu;
}
bool Client::isMenu() const
{
return windowType() == NET::Menu && !isTopMenu(); // because of backwards comp.
}
bool Client::isToolbar() const
{
return windowType() == NET::Toolbar;
}
bool Client::isSplash() const
{
return windowType() == NET::Splash;
}
bool Client::isUtility() const
{
return windowType() == NET::Utility;
}
bool Client::isDialog() const
{
return windowType() == NET::Dialog;
}
bool Client::isNormalWindow() const
{
return windowType() == NET::Normal;
}
bool Client::isSpecialWindow() const
{
return isDesktop() || isDock() || isSplash() || isTopMenu()
|| isToolbar(); // TODO
}
NET::WindowType Client::windowType( bool direct, int supported_types ) const NET::WindowType Client::windowType( bool direct, int supported_types ) const
{ {
NET::WindowType wt = info->windowType( supported_types ); NET::WindowType wt = info->windowType( supported_types );
@ -1706,6 +1643,12 @@ NET::WindowType Client::windowType( bool direct, int supported_types ) const
return wt; return wt;
} }
bool Client::isSpecialWindow() const
{
return isDesktop() || isDock() || isSplash() || isTopMenu()
|| isToolbar(); // TODO
}
/*! /*!
Sets an appropriate cursor shape for the logical mouse position \a m Sets an appropriate cursor shape for the logical mouse position \a m
@ -1802,46 +1745,24 @@ void Client::cancelAutoRaise()
autoRaiseTimer = 0; autoRaiseTimer = 0;
} }
#ifndef NDEBUG double Client::opacity() const
kdbgstream& operator<<( kdbgstream& stream, const Client* cl )
{ {
if( cl == NULL ) if( info->opacity() == 0xffffffff )
return stream << "\'NULL_CLIENT\'"; return 1.0;
return stream << "\'ID:" << cl->window() << ";WMCLASS:" << cl->resourceClass() << ":" << cl->resourceName() << ";Caption:" << cl->caption() << "\'"; return info->opacity() * 1.0 / 0xffffffff;
} }
kdbgstream& operator<<( kdbgstream& stream, const ClientList& list )
void Client::setOpacity( double opacity )
{ {
stream << "LIST:("; opacity = qBound( 0.0, opacity, 1.0 );
bool first = true; info->setOpacity( static_cast< unsigned long >( opacity * 0xffffffff ));
for( ClientList::ConstIterator it = list.begin(); // we'll react on PropertyNotify
it != list.end();
++it )
{
if( !first )
stream << ":";
first = false;
stream << *it;
}
stream << ")";
return stream;
} }
kdbgstream& operator<<( kdbgstream& stream, const ConstClientList& list )
void Client::debug( kdbgstream& stream ) const
{ {
stream << "LIST:("; stream << "\'ID:" << window() << ";WMCLASS:" << resourceClass() << ":" << resourceName() << ";Caption:" << caption() << "\'";
bool first = true;
for( ConstClientList::ConstIterator it = list.begin();
it != list.end();
++it )
{
if( !first )
stream << ":";
first = false;
stream << *it;
}
stream << ")";
return stream;
} }
#endif
QPixmap * kwin_get_menu_pix_hack() QPixmap * kwin_get_menu_pix_hack()
{ {

View file

@ -43,7 +43,7 @@ namespace KWinInternal
extern QPixmap* kwin_get_menu_pix_hack(); extern QPixmap* kwin_get_menu_pix_hack();
TabBox::TabBox( Workspace *ws, const char *name ) TabBox::TabBox( Workspace *ws, const char *name )
: Q3Frame( 0, name, Qt::WNoAutoErase ), current_client( NULL ), wspace(ws) : Q3Frame( 0, name, Qt::WNoAutoErase ), client(0), wspace(ws)
{ {
setFrameStyle(QFrame::StyledPanel | QFrame::Plain); setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
setLineWidth(2); setLineWidth(2);
@ -57,25 +57,10 @@ TabBox::TabBox( Workspace *ws, const char *name )
reconfigure(); reconfigure();
reset(); reset();
connect(&delayedShowTimer, SIGNAL(timeout()), this, SLOT(show())); connect(&delayedShowTimer, SIGNAL(timeout()), this, SLOT(show()));
XSetWindowAttributes attr;
attr.override_redirect = 1;
outline_left = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
outline_right = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
outline_top = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
outline_bottom = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
} }
TabBox::~TabBox() TabBox::~TabBox()
{ {
XDestroyWindow( display(), outline_left );
XDestroyWindow( display(), outline_right );
XDestroyWindow( display(), outline_top );
XDestroyWindow( display(), outline_bottom );
} }
@ -126,9 +111,7 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client
else if( !list.contains( modal )) else if( !list.contains( modal ))
list += modal; list += modal;
else else
{ ; // nothing
// nothing
}
} }
} }
@ -164,10 +147,10 @@ void TabBox::reset()
if ( mode() == WindowsMode ) if ( mode() == WindowsMode )
{ {
setCurrentClient( workspace()->activeClient()); client = workspace()->activeClient();
// get all clients to show // get all clients to show
createClientList(clients, options_traverse_all ? -1 : workspace()->currentDesktop(), current_client, true); createClientList(clients, options_traverse_all ? -1 : workspace()->currentDesktop(), client, true);
// calculate maximum caption width // calculate maximum caption width
cw = fontMetrics().width(no_tasks)+20; cw = fontMetrics().width(no_tasks)+20;
@ -244,8 +227,7 @@ void TabBox::nextPrev( bool next)
{ {
if ( mode() == WindowsMode ) if ( mode() == WindowsMode )
{ {
Client* firstClient = NULL; Client* firstClient = 0;
Client* client = current_client;
do do
{ {
if ( next ) if ( next )
@ -265,7 +247,6 @@ void TabBox::nextPrev( bool next)
break; break;
} }
} while ( client && !clients.contains( client )); } while ( client && !clients.contains( client ));
setCurrentClient( client );
} }
else if( mode() == DesktopMode ) else if( mode() == DesktopMode )
{ {
@ -303,18 +284,9 @@ Client* TabBox::currentClient()
{ {
if ( mode() != WindowsMode ) if ( mode() != WindowsMode )
return 0; return 0;
if (!workspace()->hasClient( current_client )) if (!workspace()->hasClient( client ))
return 0; return 0;
return current_client; return client;
}
void TabBox::setCurrentClient( Client* c )
{
if( current_client != c )
{
current_client = c;
updateOutline();
}
} }
/*! /*!
@ -336,11 +308,6 @@ int TabBox::currentDesktop()
*/ */
void TabBox::showEvent( QShowEvent* ) void TabBox::showEvent( QShowEvent* )
{ {
updateOutline();
XRaiseWindow( display(), outline_left );
XRaiseWindow( display(), outline_right );
XRaiseWindow( display(), outline_top );
XRaiseWindow( display(), outline_bottom );
raise(); raise();
} }
@ -350,10 +317,6 @@ void TabBox::showEvent( QShowEvent* )
*/ */
void TabBox::hideEvent( QHideEvent* ) void TabBox::hideEvent( QHideEvent* )
{ {
XUnmapWindow( display(), outline_left );
XUnmapWindow( display(), outline_right );
XUnmapWindow( display(), outline_top );
XUnmapWindow( display(), outline_bottom );
} }
/*! /*!
@ -392,7 +355,7 @@ void TabBox::drawContents( QPainter * )
if ( workspace()->hasClient( *it ) ) // safety if ( workspace()->hasClient( *it ) ) // safety
{ {
// draw highlight background // draw highlight background
if ( (*it) == current_client ) if ( (*it) == currentClient() )
p.fillRect(x, y, r.width(), lineHeight, palette().brush( QPalette::Highlight )); p.fillRect(x, y, r.width(), lineHeight, palette().brush( QPalette::Highlight ));
// draw icon // draw icon
@ -426,10 +389,10 @@ void TabBox::drawContents( QPainter * )
else else
s += (*it)->caption(); s += (*it)->caption();
s = fontMetrics().elidedText(s, Qt::ElideMiddle, r.width() - 5 - iconWidth - 8); s = KStringHandler::cPixelSqueeze(s, fontMetrics(), r.width() - 5 - iconWidth - 8);
// draw text // draw text
if ( (*it) == current_client ) if ( (*it) == currentClient() )
p.setPen(palette().color( QPalette::HighlightedText )); p.setPen(palette().color( QPalette::HighlightedText ));
else if( (*it)->isMinimized()) else if( (*it)->isMinimized())
{ {
@ -547,91 +510,6 @@ void TabBox::drawContents( QPainter * )
localPainter.drawImage( QPoint( r.x(), r.y() ), pix.toImage() ); localPainter.drawImage( QPoint( r.x(), r.y() ), pix.toImage() );
} }
void TabBox::updateOutline()
{
Client* c = currentClient();
if( c == NULL || this->isHidden() || !c->isShown( true ) || !c->isOnCurrentDesktop())
{
XUnmapWindow( display(), outline_left );
XUnmapWindow( display(), outline_right );
XUnmapWindow( display(), outline_top );
XUnmapWindow( display(), outline_bottom );
return;
}
// left/right parts are between top/bottom, they don't reach as far as the corners
XMoveResizeWindow( display(), outline_left, c->x(), c->y() + 5, 5, c->height() - 10 );
XMoveResizeWindow( display(), outline_right, c->x() + c->width() - 5, c->y() + 5, 5, c->height() - 10 );
XMoveResizeWindow( display(), outline_top, c->x(), c->y(), c->width(), 5 );
XMoveResizeWindow( display(), outline_bottom, c->x(), c->y() + c->height() - 5, c->width(), 5 );
{
QPixmap pix( 5, c->height() - 10 );
QPainter p( &pix );
p.setPen( Qt::white );
p.drawLine( 0, 0, 0, pix.height() - 1 );
p.drawLine( 4, 0, 4, pix.height() - 1 );
p.setPen( Qt::gray );
p.drawLine( 1, 0, 1, pix.height() - 1 );
p.drawLine( 3, 0, 3, pix.height() - 1 );
p.setPen( Qt::black );
p.drawLine( 2, 0, 2, pix.height() - 1 );
p.end();
XSetWindowBackgroundPixmap( display(), outline_left, pix.handle());
XSetWindowBackgroundPixmap( display(), outline_right, pix.handle());
}
{
QPixmap pix( c->width(), 5 );
QPainter p( &pix );
p.setPen( Qt::white );
p.drawLine( 0, 0, pix.width() - 1 - 0, 0 );
p.drawLine( 4, 4, pix.width() - 1 - 4, 4 );
p.drawLine( 0, 0, 0, 4 );
p.drawLine( pix.width() - 1 - 0, 0, pix.width() - 1 - 0, 4 );
p.setPen( Qt::gray );
p.drawLine( 1, 1, pix.width() - 1 - 1, 1 );
p.drawLine( 3, 3, pix.width() - 1 - 3, 3 );
p.drawLine( 1, 1, 1, 4 );
p.drawLine( 3, 3, 3, 4 );
p.drawLine( pix.width() - 1 - 1, 1, pix.width() - 1 - 1, 4 );
p.drawLine( pix.width() - 1 - 3, 3, pix.width() - 1 - 3, 4 );
p.setPen( Qt::black );
p.drawLine( 2, 2, pix.width() - 1 - 2, 2 );
p.drawLine( 2, 2, 2, 4 );
p.drawLine( pix.width() - 1 - 2, 2, pix.width() - 1 - 2, 4 );
p.end();
XSetWindowBackgroundPixmap( display(), outline_top, pix.handle());
}
{
QPixmap pix( c->width(), 5 );
QPainter p( &pix );
p.setPen( Qt::white );
p.drawLine( 4, 0, pix.width() - 1 - 4, 0 );
p.drawLine( 0, 4, pix.width() - 1 - 0, 4 );
p.drawLine( 0, 4, 0, 0 );
p.drawLine( pix.width() - 1 - 0, 4, pix.width() - 1 - 0, 0 );
p.setPen( Qt::gray );
p.drawLine( 3, 1, pix.width() - 1 - 3, 1 );
p.drawLine( 1, 3, pix.width() - 1 - 1, 3 );
p.drawLine( 3, 1, 3, 0 );
p.drawLine( 1, 3, 1, 0 );
p.drawLine( pix.width() - 1 - 3, 1, pix.width() - 1 - 3, 0 );
p.drawLine( pix.width() - 1 - 1, 3, pix.width() - 1 - 1, 0 );
p.setPen( Qt::black );
p.drawLine( 2, 2, pix.width() - 1 - 2, 2 );
p.drawLine( 2, 0, 2, 2 );
p.drawLine( pix.width() - 1 - 2, 0, pix.width() - 1 - 2 , 2 );
p.end();
XSetWindowBackgroundPixmap( display(), outline_bottom, pix.handle());
}
XClearWindow( display(), outline_left );
XClearWindow( display(), outline_right );
XClearWindow( display(), outline_top );
XClearWindow( display(), outline_bottom );
XMapWindow( display(), outline_left );
XMapWindow( display(), outline_right );
XMapWindow( display(), outline_top );
XMapWindow( display(), outline_bottom );
}
void TabBox::hide() void TabBox::hide()
{ {
delayedShowTimer.stop(); delayedShowTimer.stop();
@ -709,7 +587,7 @@ void TabBox::handleMouseEvent( XEvent* e )
{ {
if( workspace()->hasClient( *it ) && (num == 0) ) // safety if( workspace()->hasClient( *it ) && (num == 0) ) // safety
{ {
setCurrentClient( *it ); client = *it;
break; break;
} }
num--; num--;

View file

@ -101,22 +101,18 @@ QMenu* Workspace::clientPopup()
desk_popup_index = popup->actions().count(); desk_popup_index = popup->actions().count();
if (options->useTranslucency){ if (options->useTranslucency){
QMenu *trans_popup = new QMenu( popup ); trans_popup = new QMenu( popup );
QVBoxLayout *transLayout = new QVBoxLayout(trans_popup); trans_popup->setFont(KGlobalSettings::menuFont());
trans_popup->setLayout( transLayout ); connect( trans_popup, SIGNAL( triggered(QAction*) ), this, SLOT( setPopupClientOpacity(QAction*)));
transButton = new QPushButton(trans_popup); const int levels[] = { 100, 90, 75, 50, 25, 10 };
transButton->setObjectName("transButton"); for( unsigned int i = 0;
transButton->setToolTip( i18n("Reset opacity to default value")); i < sizeof( levels ) / sizeof( levels[ 0 ] );
transSlider = new QSlider(trans_popup); ++i )
transSlider->setObjectName( "transSlider" ); {
transSlider->setRange( 0, 100 ); action = trans_popup->addAction( QString::number( levels[ i ] ) + "%" );
transSlider->setValue( 100 ); action->setCheckable( true );
transSlider->setOrientation( Qt::Vertical ); action->setData( levels[ i ] );
transSlider->setToolTip( i18n("Slide this to set the window's opacity")); }
connect(transButton, SIGNAL(clicked()), SLOT(resetClientOpacity()));
connect(transButton, SIGNAL(clicked()), trans_popup, SLOT(hide()));
connect(transSlider, SIGNAL(valueChanged(int)), SLOT(setTransButtonText(int)));
connect(transSlider, SIGNAL(valueChanged(int)), this, SLOT(setPopupClientOpacity(int)));
action = popup->addMenu( trans_popup ); action = popup->addMenu( trans_popup );
action->setText( i18n("&Opacity") ); action->setText( i18n("&Opacity") );
} }
@ -163,31 +159,14 @@ QMenu* Workspace::clientPopup()
return popup; return popup;
} }
//sets the transparency of the client to given value(given by slider) void Workspace::setPopupClientOpacity( QAction* action )
void Workspace::setPopupClientOpacity(int value)
{ {
// TODO if( active_popup_client == NULL )
return;
int level = action->data().toInt();
active_popup_client->setOpacity( level / 100.0 );
} }
void Workspace::setTransButtonText(int value)
{
value = 100 - value;
if(value < 0)
transButton->setText("000 %");
else if (value >= 100 )
transButton->setText("100 %");
else if(value < 10)
transButton->setText("00"+QString::number(value)+" %");
else if(value < 100)
transButton->setText('0'+QString::number(value)+" %");
}
void Workspace::resetClientOpacity()
{
// TODO
}
/*! /*!
The client popup menu will become visible soon. The client popup menu will become visible soon.
@ -222,6 +201,16 @@ void Workspace::clientPopupAboutToShow()
mNoBorderOpAction->setChecked( active_popup_client->noBorder() ); mNoBorderOpAction->setChecked( active_popup_client->noBorder() );
mMinimizeOpAction->setEnabled( active_popup_client->isMinimizable() ); mMinimizeOpAction->setEnabled( active_popup_client->isMinimizable() );
mCloseOpAction->setEnabled( active_popup_client->isCloseable() ); mCloseOpAction->setEnabled( active_popup_client->isCloseable() );
if (options->useTranslucency)
{
foreach( QAction* action, trans_popup->actions())
{
if( action->data().toInt() == qRound( active_popup_client->opacity() * 100 ))
action->setChecked( true );
else
action->setChecked( false );
}
}
} }
@ -640,10 +629,10 @@ bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPo
workspace()->windowToNextDesktop( this ); workspace()->windowToNextDesktop( this );
break; break;
case Options::MouseOpacityMore: case Options::MouseOpacityMore:
// TODO setOpacity( qMin( opacity() + 0.1, 1.0 ));
break; break;
case Options::MouseOpacityLess: case Options::MouseOpacityLess:
// TODO setOpacity( qMax( opacity() - 0.1, 0.0 ));
break; break;
case Options::MouseNothing: case Options::MouseNothing:
replay = true; replay = true;

View file

@ -30,6 +30,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <QX11Info> #include <QX11Info>
#include <stdio.h> #include <stdio.h>
#include "atoms.h" #include "atoms.h"
@ -42,19 +43,68 @@ namespace KWinInternal
#ifndef KCMRULES #ifndef KCMRULES
// used to store the return values of bool Extensions::has_shape = false;
// XShapeQueryExtension. int Extensions::shape_event_base = 0;
// Necessary since shaped window are an extension to X bool Extensions::has_randr = false;
int Shape::kwin_shape_version = 0; int Extensions::randr_event_base = 0;
int Shape::kwin_shape_event = 0; bool Extensions::has_damage = false;
int Extensions::damage_event_base = 0;
bool Extensions::has_composite = false;
bool Extensions::has_composite_overlay = false;
bool Extensions::has_fixes = false;
// does the window w need a shape combine mask around it? void Extensions::init()
bool Shape::hasShape( WId w) {
int dummy;
has_shape = XShapeQueryExtension( display(), &shape_event_base, &dummy);
#ifdef HAVE_XRANDR
has_randr = XRRQueryExtension( display(), &randr_event_base, &dummy );
if( has_randr )
{
int major, minor;
XRRQueryVersion( display(), &major, &minor );
has_randr = ( major > 1 || ( major == 1 && minor >= 1 ) );
}
#else
has_randr = false;
#endif
#ifdef HAVE_XDAMAGE
has_damage = XDamageQueryExtension( display(), &damage_event_base, &dummy );
#else
has_damage = false;
#endif
#ifdef HAVE_XCOMPOSITE
has_composite = XCompositeQueryExtension( display(), &dummy, &dummy );
if( has_composite )
{
int major, minor;
XCompositeQueryVersion( display(), &major, &minor );
has_composite = ( major > 0 || minor >= 2 );
has_composite_overlay = ( major > 0 || minor >= 3 );
}
#else
has_composite = false;
has_composite_overlay = false;
#endif
#ifdef HAVE_XFIXES
has_fixes = XFixesQueryExtension( display(), &dummy, &dummy );
#else
has_fixes = false;
#endif
}
int Extensions::shapeNotifyEvent()
{
return shape_event_base + ShapeNotify;
}
// does the window w need a shape combine mask around it?
bool Extensions::hasShape( Window w )
{ {
int xws, yws, xbs, ybs; int xws, yws, xbs, ybs;
unsigned int wws, hws, wbs, hbs; unsigned int wws, hws, wbs, hbs;
int boundingShaped = 0, clipShaped = 0; int boundingShaped = 0, clipShaped = 0;
if (!available()) if( !Extensions::shapeAvailable())
return false; return false;
XShapeQueryExtents(display(), w, XShapeQueryExtents(display(), w,
&boundingShaped, &xws, &yws, &wws, &hws, &boundingShaped, &xws, &yws, &wws, &hws,
@ -62,21 +112,22 @@ bool Shape::hasShape( WId w)
return boundingShaped != 0; return boundingShaped != 0;
} }
int Shape::shapeEvent() int Extensions::randrNotifyEvent()
{ {
return kwin_shape_event; #ifdef HAVE_XRANDR
return randr_event_base + RRScreenChangeNotify;
#else
return 0;
#endif
} }
void Shape::init() int Extensions::damageNotifyEvent()
{ {
kwin_shape_version = 0; #ifdef HAVE_XDAMAGE
int dummy; return damage_event_base + XDamageNotify;
if( !XShapeQueryExtension( display(), &kwin_shape_event, &dummy )) #else
return; return 0;
int major, minor; #endif
if( !XShapeQueryVersion( display(), &major, &minor ))
return;
kwin_shape_version = major * 0x10 + minor;
} }
void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move, void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
@ -300,7 +351,6 @@ bool grabbedXServer()
{ {
return server_grab_count > 0; return server_grab_count > 0;
} }
#endif #endif
bool isLocalMachine( const QByteArray& host ) bool isLocalMachine( const QByteArray& host )
@ -364,8 +414,6 @@ void ShortcutDialog::accept()
KShortcutDialog::accept(); KShortcutDialog::accept();
} }
#endif #endif
} // namespace } // namespace
#ifndef KCMRULES #ifndef KCMRULES

View file

@ -573,7 +573,7 @@ void Workspace::removeClient( Client* c, allowed_t )
if( client_keys_client == c ) if( client_keys_client == c )
setupWindowShortcutDone( false ); setupWindowShortcutDone( false );
if( !c->shortcut().isNull()) if( !c->shortcut().isEmpty())
c->setShortcut( QString() ); // remove from client_keys c->setShortcut( QString() ); // remove from client_keys
if( c->isDialog()) if( c->isDialog())
@ -2403,7 +2403,7 @@ void Workspace::helperDialog( const QString& message, const Client* c )
{ {
KAction* action = keys->action( "Window Operations Menu" ); KAction* action = keys->action( "Window Operations Menu" );
QString shortcut = QString( "%1 (%2)" ).arg( action->text() ) QString shortcut = QString( "%1 (%2)" ).arg( action->text() )
.arg( action->globalShortcut().seq( 0 ).toString()); .arg( action->globalShortcut().primary().toString());
args << "--msgbox" << args << "--msgbox" <<
i18n( "You have selected to show a window without its border.\n" i18n( "You have selected to show a window without its border.\n"
"Without the border, you will not be able to enable the border " "Without the border, you will not be able to enable the border "
@ -2416,7 +2416,7 @@ void Workspace::helperDialog( const QString& message, const Client* c )
{ {
KAction* action = keys->action( "Window Operations Menu" ); KAction* action = keys->action( "Window Operations Menu" );
QString shortcut = QString( "%1 (%2)" ).arg( action->text() ) QString shortcut = QString( "%1 (%2)" ).arg( action->text() )
.arg( action->globalShortcut().seq( 0 ).toString()); .arg( action->globalShortcut().primary().toString());
args << "--msgbox" << args << "--msgbox" <<
i18n( "You have selected to show a window in fullscreen mode.\n" i18n( "You have selected to show a window in fullscreen mode.\n"
"If the application itself does not have an option to turn the fullscreen " "If the application itself does not have an option to turn the fullscreen "