Reduce the difference between noborder requested by the application

and set by the user - they're now interchangeable. Which means
that Alt+F3/Advanced/No border can put the window decoration
back on the KRunner window regardless of what Plasma or any other
app thinks.


svn path=/trunk/KDE/kdebase/workspace/; revision=788964
This commit is contained in:
Luboš Luňák 2008-03-23 00:12:11 +00:00
parent cc81fecbf6
commit e7c88f309d
8 changed files with 76 additions and 54 deletions

View file

@ -145,7 +145,7 @@ Client::Client( Workspace *ws )
hidden = false;
modal = false;
noborder = false;
user_noborder = false;
app_noborder = false;
urgency = false;
ignore_focus_stealing = false;
demands_attention = false;
@ -420,6 +420,7 @@ void Client::detectNoBorder()
if( shape())
{
noborder = true;
app_noborder = true;
return;
}
switch( windowType())
@ -429,6 +430,7 @@ void Client::detectNoBorder()
case NET::TopMenu :
case NET::Splash :
noborder = true;
app_noborder = true;
break;
case NET::Unknown :
case NET::Normal :
@ -445,7 +447,10 @@ void Client::detectNoBorder()
// just meaning "noborder", so let's treat it only as such flag, and ignore it as
// a window type otherwise (SUPPORTED_WINDOW_TYPES_MASK doesn't include it)
if( info->windowType( SUPPORTED_MANAGED_WINDOW_TYPES_MASK | NET::OverrideMask ) == NET::Override )
{
noborder = true;
app_noborder = true;
}
}
void Client::updateFrameExtents()
@ -478,27 +483,22 @@ void Client::resizeDecoration( const QSize& s )
bool Client::noBorder() const
{
return noborder || isFullScreen() || user_noborder;
return noborder || isFullScreen();
}
bool Client::userCanSetNoBorder() const
{
return !noborder && !isFullScreen() && !isShade();
return !isFullScreen() && !isShade();
}
bool Client::isUserNoBorder() const
{
return user_noborder;
}
void Client::setUserNoBorder( bool set )
void Client::setNoBorder( bool set )
{
if( !userCanSetNoBorder())
return;
set = rules()->checkNoBorder( set );
if( user_noborder == set )
if( noborder == set )
return;
user_noborder = set;
noborder = set;
updateDecoration( true, false );
updateWindowRules();
}
@ -506,19 +506,20 @@ void Client::setUserNoBorder( bool set )
void Client::updateShape()
{
// workaround for #19644 - shaped windows shouldn't have decoration
if( shape() && !noBorder())
{
noborder = true;
updateDecoration( true );
}
if( shape())
{
XShapeCombineShape(display(), frameId(), ShapeBounding,
clientPos().x(), clientPos().y(),
window(), ShapeBounding, ShapeSet);
if( !app_noborder ) // only when shape is detected for the first time,
{ // still let the user to override
app_noborder = true;
noborder = true;
updateDecoration( true );
}
}
// !shape() mask setting is done in setMask() when the decoration
// calls it or when the decoration is created/destroyed
if( shape() && noBorder())
XShapeCombineShape( display(), frameId(), ShapeBounding,
clientPos().x(), clientPos().y(), window(), ShapeBounding, ShapeSet );
// Decoration mask (i.e. 'else' here) setting is done in setMask()
// when the decoration calls it or when the decoration is created/destroyed
updateInputShape();
if( compositing())
addDamageFull();
@ -528,6 +529,8 @@ void Client::updateShape()
static_cast<EffectsHandlerImpl*>(effects)->windowGeometryShapeChanged( effectWindow(), geometry());
}
static Window shape_helper_window = None;
void Client::updateInputShape()
{
if( hidden_preview ) // sets it to none, don't change
@ -542,34 +545,43 @@ void Client::updateInputShape()
// 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)
// TODO it seems there is, after all - XShapeGetRectangles()
static Window helper_window = None;
if( helper_window == None )
helper_window = XCreateSimpleWindow( display(), rootWindow(),
// TODO it seems there is, after all - XShapeGetRectangles() - but maybe this is better
if( shape_helper_window == None )
shape_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,
XResizeWindow( display(), shape_helper_window, width(), height());
XShapeCombineShape( display(), shape_helper_window, ShapeInput, 0, 0,
frameId(), ShapeBounding, ShapeSet );
XShapeCombineShape( display(), helper_window, ShapeInput,
XShapeCombineShape( display(), shape_helper_window, ShapeInput,
clientPos().x(), clientPos().y(),
window(), ShapeBounding, ShapeSubtract );
XShapeCombineShape( display(), helper_window, ShapeInput,
XShapeCombineShape( display(), shape_helper_window, ShapeInput,
clientPos().x(), clientPos().y(),
window(), ShapeInput, ShapeUnion );
XShapeCombineShape( display(), frameId(), ShapeInput, 0, 0,
helper_window, ShapeInput, ShapeSet );
shape_helper_window, ShapeInput, ShapeSet );
}
}
void Client::setMask( const QRegion& reg, int mode )
{
if( _mask == reg )
return;
_mask = reg;
Window shape_window = frameId();
if( shape())
{
// the same way of applying a shape without strange intermediate states like above
if( shape_helper_window == None )
shape_helper_window = XCreateSimpleWindow( display(), rootWindow(),
0, 0, 1, 1, 0, 0, 0 );
shape_window = shape_helper_window;
}
if( reg.isEmpty())
XShapeCombineMask( display(), frameId(), ShapeBounding, 0, 0,
XShapeCombineMask( display(), shape_window, ShapeBounding, 0, 0,
None, ShapeSet );
else if( mode == X::Unsorted )
XShapeCombineRegion( display(), frameId(), ShapeBounding, 0, 0,
XShapeCombineRegion( display(), shape_window, ShapeBounding, 0, 0,
reg.handle(), ShapeSet );
else
{
@ -584,10 +596,21 @@ void Client::setMask( const QRegion& reg, int mode )
xrects[ i ].width = rects[ i ].width();
xrects[ i ].height = rects[ i ].height();
}
XShapeCombineRectangles( display(), frameId(), ShapeBounding, 0, 0,
XShapeCombineRectangles( display(), shape_window, ShapeBounding, 0, 0,
xrects, rects.count(), ShapeSet, mode );
delete[] xrects;
}
if( shape())
{ // the rest of the applyign using a temporary window
XRectangle rec = { 0, 0, clientSize().width(), clientSize().height() };
XShapeCombineRectangles( display(), shape_helper_window, ShapeBounding,
clientPos().x(), clientPos().y(), &rec, 1, ShapeSubtract, Unsorted );
XShapeCombineShape( display(), shape_helper_window, ShapeBounding,
clientPos().x(), clientPos().y(),
window(), ShapeBounding, ShapeUnion );
XShapeCombineShape( display(), frameId(), ShapeBounding, 0, 0,
shape_helper_window, ShapeBounding, ShapeSet );
}
if( compositing())
addDamageFull();
if( scene != NULL )
@ -1446,7 +1469,10 @@ void Client::getMotifHints()
bool mnoborder, mresize, mmove, mminimize, mmaximize, mclose;
Motif::readFlags( client, mnoborder, mresize, mmove, mminimize, mmaximize, mclose );
if( mnoborder )
{
noborder = true;
app_noborder = true;
}
if( !hasNETSupport()) // NETWM apps should set type and size constraints
{
motif_may_resize = mresize; // this should be set using minsize==maxsize, but oh well

View file

@ -156,10 +156,9 @@ class Client
QRect geometryFSRestore() const { return geom_fs_restore; } // only for session saving
int fullScreenMode() const { return fullscreen_mode; } // only for session saving
bool isUserNoBorder() const;
void setUserNoBorder( bool set );
bool userCanSetNoBorder() const;
bool noBorder() const;
void setNoBorder( bool set );
bool userCanSetNoBorder() const;
bool skipTaskbar( bool from_outside = false ) const;
void setSkipTaskbar( bool set, bool from_outside );
@ -455,7 +454,7 @@ class Client
uint hidden : 1; // forcibly hidden by calling hide()
uint modal : 1; // NET::Modal
uint noborder : 1;
uint user_noborder : 1;
uint app_noborder : 1; // the app requested no border using something (window type, motif hints)
uint urgency : 1; // XWMHints, UrgencyHint
uint ignore_focus_stealing : 1; // don't apply focus stealing prevention to this client
uint demands_attention : 1;

View file

@ -2199,7 +2199,7 @@ void Client::setFullScreen( bool set, bool user )
int Client::checkFullScreenHack( const QRect& geom ) const
{
// if it's noborder window, and has size of one screen or the whole desktop geometry, it's fullscreen hack
if( noBorder() && !isUserNoBorder() && isFullScreenable( true ))
if( noBorder() && app_noborder && isFullScreenable( true ))
{
if( geom.size() == workspace()->clientArea( FullArea, geom.center(), desktop()).size())
return 2; // full area fullscreen hack

View file

@ -140,20 +140,16 @@ bool Client::manage( Window w, bool isMapped )
workspace()->updateClientLayer( this );
SessionInfo* session = workspace()->takeSessionInfo( this );
if ( session )
if( session )
{
if ( session->minimized )
init_minimize = true;
if( session->userNoBorder )
setUserNoBorder( true );
init_minimize = session->minimized;
noborder = session->noBorder;
}
setShortcut( rules()->checkShortcut( session ? session->shortcut : QString(), true ));
init_minimize = rules()->checkMinimize( init_minimize, !isMapped );
if( rules()->checkNoBorder( false, !isMapped ))
setUserNoBorder( true );
noborder = rules()->checkNoBorder( noborder, !isMapped );
// initial desktop placement
if ( session )

View file

@ -495,8 +495,8 @@ bool Rules::update( Client* c )
}
if( noborderrule == ( SetRule )Remember)
{
updated = updated || noborder != c->isUserNoBorder();
noborder = c->isUserNoBorder();
updated = updated || noborder != c->noBorder();
noborder = c->noBorder();
}
if (opacityactiverule == ( ForceRule )Force)
{
@ -838,7 +838,7 @@ void Client::applyWindowRules()
setKeepAbove( keepAbove());
setKeepBelow( keepBelow());
setFullScreen( isFullScreen(), true );
setUserNoBorder( isUserNoBorder());
setNoBorder( noBorder());
// FSP
// AcceptFocus :
if( workspace()->mostRecentlyActivatedClient() == this

5
sm.cpp
View file

@ -121,7 +121,8 @@ void Workspace::storeSession( KConfig* config, SMSavePhase phase )
cg.writeEntry( QString("keepBelow")+n, c->keepBelow() );
cg.writeEntry( QString("skipTaskbar")+n, c->skipTaskbar( true ) );
cg.writeEntry( QString("skipPager")+n, c->skipPager() );
cg.writeEntry( QString("userNoBorder")+n, c->isUserNoBorder() );
// not really just set by user, but name kept for back. comp. reasons
cg.writeEntry( QString("userNoBorder")+n, c->noBorder() );
cg.writeEntry( QString("windowType")+n, windowTypeToTxt( c->windowType()));
cg.writeEntry( QString("shortcut")+n, c->shortcut().toString());
cg.writeEntry( QString("stackingOrder")+n, unconstrained_stacking_order.indexOf( c ));
@ -185,7 +186,7 @@ void Workspace::loadSessionInfo()
info->keepBelow = cg.readEntry( QString("keepBelow")+n, false );
info->skipTaskbar = cg.readEntry( QString("skipTaskbar")+n, false );
info->skipPager = cg.readEntry( QString("skipPager")+n, false );
info->userNoBorder = cg.readEntry( QString("userNoBorder")+n, false );
info->noBorder = cg.readEntry( QString("userNoBorder")+n, false );
info->windowType = txtToWindowType( cg.readEntry( QString("windowType")+n, QString() ).toLatin1());
info->shortcut = cg.readEntry( QString("shortcut")+n, QString() );
info->active = ( active_client == i );

2
sm.h
View file

@ -56,7 +56,7 @@ struct SessionInfo
bool keepBelow;
bool skipTaskbar;
bool skipPager;
bool userNoBorder;
bool noBorder;
NET::WindowType windowType;
QString shortcut;
bool active; // means 'was active in the saved session'

View file

@ -499,7 +499,7 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
c->setFullScreen( !c->isFullScreen(), true );
break;
case Options::NoBorderOp:
c->setUserNoBorder( !c->isUserNoBorder());
c->setNoBorder( !c->noBorder());
break;
case Options::KeepAboveOp:
{