@ -588,26 +588,27 @@ bool Client::sameAppWindowRoleMatch(const Client* c1, const Client* c2, bool act
void Client : : readTransient ( )
{
TRANSIENCY_CHECK ( this ) ;
Window new_transient_for_id ;
if ( XGetTransientForHint ( display ( ) , window ( ) , & new_transient_for_id ) ) {
original_transient_for_id = new_transient_for_id ;
Xcb : : TransientFor transientFor ( window ( ) ) ;
xcb_window_t new_transient_for_id = XCB_WINDOW_NONE ;
if ( transientFor . getTransientFor ( & new_transient_for_id ) ) {
m_originalTransientForId = new_transient_for_id ;
new_transient_for_id = verifyTransientFor ( new_transient_for_id , true ) ;
} else {
original_transient_for_id = None ;
new_transient_for_id = verifyTransientFor ( None , false ) ;
m_originalTransientForId = XCB_WINDOW_NONE ;
new_transient_for_id = verifyTransientFor ( XCB_WINDOW_NONE , false ) ;
}
setTransient ( new_transient_for_id ) ;
}
void Client : : setTransient ( Window new_transient_for_id )
void Client : : setTransient ( xcb_window_t new_transient_for_id )
{
TRANSIENCY_CHECK ( this ) ;
if ( new_transient_for_id ! = transient_for_i d) {
if ( new_transient_for_id ! = m_transientForI d) {
removeFromMainClients ( ) ;
transient_for = NULL ;
transient_for_i d = new_transient_for_id ;
if ( transient_for_id ! = None & & ! groupTransient ( ) ) {
transient_for = workspace ( ) - > findClient ( WindowMatchPredicate ( transient_for_i d) ) ;
m_transientForI d = new_transient_for_id ;
if ( m_transientForId ! = XCB_WINDOW_NONE & & ! groupTransient ( ) ) {
transient_for = workspace ( ) - > findClient ( WindowMatchPredicate ( m_transientForI d) ) ;
assert ( transient_for ! = NULL ) ; // verifyTransient() had to check this
transient_for - > addTransient ( this ) ;
} // checkGroup() will check 'check_active_modal'
@ -755,18 +756,18 @@ void Client::checkGroupTransients()
/*!
Check that the window is not transient for itself , and similar nonsense .
*/
Window Client : : verifyTransientFor ( Window new_transient_for , bool defined )
xcb_window_t Client : : verifyTransientFor ( xcb_window_t new_transient_for , bool set )
{
Window new_property_value = new_transient_for ;
xcb_window_t new_property_value = new_transient_for ;
// make sure splashscreens are shown above all their app's windows, even though
// they're in Normal layer
if ( isSplash ( ) & & new_transient_for = = None )
if ( isSplash ( ) & & new_transient_for = = XCB_WINDOW_NONE )
new_transient_for = rootWindow ( ) ;
if ( new_transient_for = = None ) {
if ( defined ) // sometimes WM_TRANSIENT_FOR is set to None, instead of root window
if ( new_transient_for = = XCB_WINDOW_NONE ) {
if ( set ) // sometimes WM_TRANSIENT_FOR is set to None, instead of root window
new_property_value = new_transient_for = rootWindow ( ) ;
else
return None ;
return XCB_WINDOW_NONE ;
}
if ( new_transient_for = = window ( ) ) { // pointing to self
// also fix the property itself
@ -776,19 +777,15 @@ Window Client::verifyTransientFor(Window new_transient_for, bool defined)
// The transient_for window may be embedded in another application,
// so kwin cannot see it. Try to find the managed client for the
// window and fix the transient_for property if possible.
WId before_search = new_transient_for ;
while ( new_transient_for ! = None
xcb_window_t before_search = new_transient_for ;
while ( new_transient_for ! = XCB_WINDOW_NONE
& & new_transient_for ! = rootWindow ( )
& & ! workspace ( ) - > findClient ( WindowMatchPredicate ( new_transient_for ) ) ) {
Window root_return , parent_return ;
Window * wins = NULL ;
unsigned int nwins ;
int r = XQueryTree ( display ( ) , new_transient_for , & root_return , & parent_return , & wins , & nwins ) ;
if ( wins )
XFree ( ( void * ) wins ) ;
if ( r = = 0 )
Xcb : : Tree tree ( new_transient_for ) ;
if ( tree . isNull ( ) ) {
break ;
new_transient_for = parent_return ;
}
new_transient_for = tree - > parent ;
}
if ( Client * new_transient_for_client = workspace ( ) - > findClient ( WindowMatchPredicate ( new_transient_for ) ) ) {
if ( new_transient_for ! = before_search ) {
@ -802,12 +799,12 @@ Window Client::verifyTransientFor(Window new_transient_for, bool defined)
// group transients cannot cause loops, because they're considered transient only for non-transient
// windows in the group
int count = 20 ;
Window loop_pos = new_transient_for ;
while ( loop_pos ! = None & & loop_pos ! = rootWindow ( ) ) {
xcb_window_t loop_pos = new_transient_for ;
while ( loop_pos ! = XCB_WINDOW_NONE & & loop_pos ! = rootWindow ( ) ) {
Client * pos = workspace ( ) - > findClient ( WindowMatchPredicate ( loop_pos ) ) ;
if ( pos = = NULL )
break ;
loop_pos = pos - > transient_for_i d;
loop_pos = pos - > m_transientForI d;
if ( - - count = = 0 | | pos = = this ) {
kWarning ( 1216 ) < < " Client " < < this < < " caused WM_TRANSIENT_FOR loop. " ;
new_transient_for = rootWindow ( ) ;
@ -818,8 +815,8 @@ Window Client::verifyTransientFor(Window new_transient_for, bool defined)
// it's transient for a specific window, but that window is not mapped
new_transient_for = rootWindow ( ) ;
}
if ( new_property_value ! = original_transient_for_i d)
XSetTransientForHint ( display ( ) , window ( ) , new_property_value ) ;
if ( new_property_value ! = m_originalTransientForI d)
xcb_icccm_set_wm_transient_for ( connection ( ) , window ( ) , new_property_value ) ;
return new_transient_for ;
}
@ -849,18 +846,18 @@ void Client::removeTransient(Client* cl)
// cl is transient for this, but this is going away
// make cl group transient
if ( cl - > transientFor ( ) = = this ) {
cl - > transient_for_id = None ;
cl - > m_transientForId = XCB_WINDOW_NONE ;
cl - > transient_for = NULL ; // SELI
// SELI cl->setTransient( rootWindow());
cl - > setTransient ( None ) ;
cl - > setTransient ( XCB_WINDOW_NONE ) ;
}
}
// A new window has been mapped. Check if it's not a mainwindow for this already existing window.
void Client : : checkTransient ( Window w )
void Client : : checkTransient ( xcb_window_t w )
{
TRANSIENCY_CHECK ( this ) ;
if ( original_transient_for_i d ! = w )
if ( m_originalTransientForI d ! = w )
return ;
w = verifyTransientFor ( w , true ) ;
setTransient ( w ) ;