No delayed deleting of decorations. They'll have to check themselves
instead, using KDecorationFactory::exists(). Fixes #66205, and it wasn't really that good idea anyway. svn path=/trunk/kdebase/kwin/; revision=260988
This commit is contained in:
parent
52cb814d32
commit
43c71a8c72
11 changed files with 61 additions and 26 deletions
26
client.cpp
26
client.cpp
|
@ -225,7 +225,7 @@ void Client::destroyClient()
|
|||
deleteClient( this, Allowed );
|
||||
}
|
||||
|
||||
void Client::updateDecoration( bool check_workspace_pos, bool force, bool delay_delete )
|
||||
void Client::updateDecoration( bool check_workspace_pos, bool force )
|
||||
{
|
||||
if( !force && (( decoration == NULL && noBorder())
|
||||
|| ( decoration != NULL && !noBorder())))
|
||||
|
@ -233,7 +233,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force, bool delay_
|
|||
bool do_show = false;
|
||||
++block_geometry;
|
||||
if( force )
|
||||
destroyDecoration( delay_delete );
|
||||
destroyDecoration();
|
||||
if( !noBorder())
|
||||
{
|
||||
decoration = workspace()->createDecoration( bridge );
|
||||
|
@ -255,7 +255,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force, bool delay_
|
|||
do_show = true;
|
||||
}
|
||||
else
|
||||
destroyDecoration( delay_delete );
|
||||
destroyDecoration();
|
||||
if( check_workspace_pos )
|
||||
checkWorkspacePosition();
|
||||
--block_geometry;
|
||||
|
@ -265,21 +265,14 @@ void Client::updateDecoration( bool check_workspace_pos, bool force, bool delay_
|
|||
updateFrameStrut();
|
||||
}
|
||||
|
||||
void Client::destroyDecoration( bool delay_delete )
|
||||
void Client::destroyDecoration()
|
||||
{
|
||||
if( decoration != NULL )
|
||||
{
|
||||
// When selecting the noborder operation from the popup menu after clicking on the menu
|
||||
// button, the decoration should be deleted. But after closing the popup, the flow
|
||||
// of control is still in the decoration, and the decorations usually do
|
||||
// "button->setDown( false )". Therefore, delay the actual deleting.
|
||||
if( delay_delete )
|
||||
decoration->deleteLater();
|
||||
else
|
||||
delete decoration;
|
||||
delete decoration;
|
||||
decoration = NULL;
|
||||
QPoint grav = calculateGravitation( true );
|
||||
border_left = border_right = border_top = border_bottom = 0;
|
||||
decoration = NULL;
|
||||
setMask( QRegion()); // reset shape mask
|
||||
int save_workarea_diff_x = workarea_diff_x;
|
||||
int save_workarea_diff_y = workarea_diff_y;
|
||||
|
@ -395,7 +388,7 @@ void Client::setUserNoBorder( bool set )
|
|||
if( user_noborder == set )
|
||||
return;
|
||||
user_noborder = set;
|
||||
updateDecoration( true, false, true ); // delayed deletion of decoration
|
||||
updateDecoration( true, false );
|
||||
}
|
||||
|
||||
bool Client::grabInput()
|
||||
|
@ -948,10 +941,7 @@ void Client::killWindow()
|
|||
killProcess( false );
|
||||
// always kill this client at the server
|
||||
XKillClient(qt_xdisplay(), window() );
|
||||
// needs to be delayed, because this may be called from the client
|
||||
// popup menu, and there may be possibly code still touching
|
||||
// this instance after returning from killWindow()
|
||||
QTimer::singleShot( 0, this, SLOT( destroyClient()));
|
||||
destroyClient();
|
||||
}
|
||||
|
||||
// send a ping to the window using _NET_WM_PING if possible
|
||||
|
|
4
client.h
4
client.h
|
@ -180,7 +180,7 @@ class Client : public QObject, public KDecorationDefines
|
|||
|
||||
void setMask( const QRegion& r, int mode = X::Unsorted );
|
||||
|
||||
void updateDecoration( bool check_workspace_pos, bool force = false, bool delay_delete = false );
|
||||
void updateDecoration( bool check_workspace_pos, bool force = false );
|
||||
void checkBorderSizes();
|
||||
|
||||
// shape extensions
|
||||
|
@ -349,7 +349,7 @@ class Client : public QObject, public KDecorationDefines
|
|||
|
||||
void embedClient( Window w );
|
||||
void detectNoBorder();
|
||||
void destroyDecoration( bool delay_delete = false );
|
||||
void destroyDecoration();
|
||||
void updateFrameStrut();
|
||||
|
||||
void rawShow(); // just shows it
|
||||
|
|
|
@ -757,7 +757,10 @@ void B2Client::menuButtonPressed()
|
|||
{
|
||||
QPoint menupoint = button[BtnMenu]->mapToGlobal(
|
||||
button[BtnMenu]->rect().bottomLeft());
|
||||
KDecorationFactory* f = factory();
|
||||
showWindowMenu(menupoint);
|
||||
if( !f->exists( this )) // 'this' was destroyed
|
||||
return;
|
||||
button[BtnMenu]->setDown(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -1277,7 +1277,10 @@ void KDEDefaultClient::menuButtonPressed()
|
|||
|
||||
QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-1,
|
||||
button[BtnMenu]->rect().bottomLeft().y()+2 );
|
||||
KDecorationFactory* f = factory();
|
||||
showWindowMenu( button[BtnMenu]->mapToGlobal( menupoint ));
|
||||
if( !f->exists( this )) // 'this' was destroyed
|
||||
return;
|
||||
button[BtnMenu]->setDown(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -1314,7 +1314,10 @@ void KeramikClient::menuButtonPressed()
|
|||
{
|
||||
QPoint menuPoint ( button[MenuButton]->rect().bottomLeft().x() - 6,
|
||||
button[MenuButton]->rect().bottomLeft().y() + 3 );
|
||||
KDecorationFactory* f = factory();
|
||||
showWindowMenu( button[MenuButton]->mapToGlobal( menuPoint ));
|
||||
if( !f->exists( this )) // 'this' was destroyed
|
||||
return;
|
||||
button[MenuButton]->setDown(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -971,7 +971,10 @@ void QuartzClient::menuButtonPressed()
|
|||
QPoint menupoint ( button[BtnMenu]->rect().bottomLeft().x()-1,
|
||||
button[BtnMenu]->rect().bottomLeft().y()+2 );
|
||||
menupoint = button[BtnMenu]->mapToGlobal( menupoint );
|
||||
showWindowMenu(menupoint);
|
||||
KDecorationFactory* f = factory();
|
||||
showWindowMenu(menupoint);
|
||||
if( !f->exists( this )) // 'this' was destroyed
|
||||
return;
|
||||
button[BtnMenu]->setDown(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -819,7 +819,10 @@ void RedmondDeco::menuButtonPressed()
|
|||
if (!dbl) {
|
||||
QPoint menupoint(button[BtnMenu]->rect().bottomLeft().x()-3,
|
||||
button[BtnMenu]->rect().bottomLeft().y()+4);
|
||||
KDecorationFactory* f = factory();
|
||||
showWindowMenu(button[BtnMenu]->mapToGlobal(menupoint));
|
||||
if( !f->exists( this )) // 'this' was destroyed
|
||||
return;
|
||||
button[BtnMenu]->setDown(false);
|
||||
} else {
|
||||
closeWindow();
|
||||
|
|
|
@ -653,8 +653,7 @@ void Client::getWmNormalHints()
|
|||
long msize;
|
||||
if (XGetWMNormalHints(qt_xdisplay(), window(), &xSizeHint, &msize) == 0 )
|
||||
xSizeHint.flags = 0;
|
||||
// set defined values for basesize, minsize, maxsize, aspect and resizeinc,
|
||||
// even if they're not in flags
|
||||
// set defined values for the fields, even if they're not in flags
|
||||
|
||||
// basesize is just like minsize, except for minsize is not used for aspect ratios
|
||||
// keep basesize only for aspect ratios, for size increments, keep the base
|
||||
|
@ -696,7 +695,7 @@ void Client::getWmNormalHints()
|
|||
xSizeHint.max_aspect.x = INT_MAX;
|
||||
xSizeHint.max_aspect.y = 1;
|
||||
}
|
||||
if( !xSizeHint.flags & PWinGravity )
|
||||
if( ! ( xSizeHint.flags & PWinGravity ))
|
||||
xSizeHint.win_gravity = NorthWestGravity;
|
||||
if( isManaged())
|
||||
{ // update to match restrictions
|
||||
|
@ -1288,7 +1287,7 @@ void Client::setFullScreen( bool set, bool user )
|
|||
StackingUpdatesBlocker blocker( workspace());
|
||||
workspace()->updateClientLayer( this ); // active fullscreens get different layer
|
||||
info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen );
|
||||
updateDecoration( false, false, true ); // delayed deletion of decoration
|
||||
updateDecoration( false, false );
|
||||
if( isFullScreen())
|
||||
setGeometry( workspace()->clientArea( MaximizeFullArea, this ));
|
||||
else
|
||||
|
|
|
@ -366,9 +366,26 @@ class KDecoration
|
|||
*/
|
||||
QString caption() const;
|
||||
/**
|
||||
* This function invokes the window operations menu.
|
||||
* This function invokes the window operations menu. IMPORTANT: As a result
|
||||
* of this function, the decoration object that called it may be destroyed
|
||||
* after the function returns. This means that the decoration object must
|
||||
* either return immediately after calling showWindowMenu(), or it must
|
||||
* use KDecorationFactory::exists() to check it's still valid. For example,
|
||||
* the code handling clicks on the menu button should look similarly like this:
|
||||
*
|
||||
* \code
|
||||
* KDecorationFactory* f = factory(); // needs to be saved before
|
||||
* showWindowMenu( button[MenuButton]->mapToGlobal( menuPoint ));
|
||||
* if( !f->exists( this )) // destroyed, return immediately
|
||||
* return;
|
||||
* button[MenuButton]->setDown(false);
|
||||
* \endcode
|
||||
*/
|
||||
void showWindowMenu( QPoint pos );
|
||||
/**
|
||||
* This function performs the given window operation. This function may destroy
|
||||
* the current decoration object, just like showWindowMenu().
|
||||
*/
|
||||
void performWindowOperation( WindowOperation op );
|
||||
/**
|
||||
* If the decoration is non-rectangular, this function needs to be called
|
||||
|
@ -571,6 +588,8 @@ class KDecoration
|
|||
* This function can be called by the decoration to request
|
||||
* closing of the decorated window. Note that closing the window
|
||||
* also involves destroying the decoration.
|
||||
* IMPORTANT: This function may destroy the current decoration object,
|
||||
* just like showWindowMenu().
|
||||
*/
|
||||
void closeWindow();
|
||||
/**
|
||||
|
|
|
@ -52,6 +52,11 @@ QValueList< KDecorationDefines::BorderSize > KDecorationFactory::borderSizes() c
|
|||
return QValueList< BorderSize >() << BorderNormal;
|
||||
}
|
||||
|
||||
bool KDecorationFactory::exists( const KDecoration* deco ) const
|
||||
{
|
||||
return _decorations.contains( const_cast< KDecoration* >( deco ));
|
||||
}
|
||||
|
||||
void KDecorationFactory::addDecoration( KDecoration* deco )
|
||||
{
|
||||
_decorations.append( deco );
|
||||
|
|
|
@ -77,6 +77,13 @@ class KDecorationFactory
|
|||
* configuration settings for the decoration.
|
||||
*/
|
||||
const KDecorationOptions* options(); // convenience
|
||||
/**
|
||||
* Returns true if the given decoration object still exists. This is necessary
|
||||
* e.g. when calling KDecoration::showWindowMenu(), which may cause the decoration
|
||||
* to be destroyed. Note that this function is reliable only if called immediately
|
||||
* after such actions.
|
||||
*/
|
||||
bool exists( const KDecoration* deco ) const;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue