SVN_SILENT Standardized coding style on main.* and manage.cpp
svn path=/trunk/KDE/kdebase/workspace/; revision=898632
This commit is contained in:
parent
038667db7a
commit
04d84ae446
3 changed files with 384 additions and 396 deletions
353
main.cpp
353
main.cpp
|
@ -69,31 +69,39 @@ Atoms* atoms;
|
|||
int screen_number = -1;
|
||||
|
||||
static bool initting = false;
|
||||
// Whether to run Xlib in synchronous mode and print backtraces for X errors.
|
||||
// Note that you most probably need to configure cmake with "-D__KDE_HAVE_GCC_VISIBILITY=0"
|
||||
// and -rdynamic in CXXFLAGS for kBacktrace() to work.
|
||||
|
||||
/**
|
||||
* Whether to run Xlib in synchronous mode and print backtraces for X errors.
|
||||
* Note that you most probably need to configure cmake with "-D__KDE_HAVE_GCC_VISIBILITY=0"
|
||||
* and -rdynamic in CXXFLAGS for kBacktrace() to work.
|
||||
*/
|
||||
static bool kwin_sync = false;
|
||||
|
||||
// this is copied from KXErrorHandler and modified to explicitly use known extensions
|
||||
/**
|
||||
* Outputs: "Error: <error> (<value>), Request: <request>(<value>), Resource: <value>"
|
||||
*/
|
||||
// This is copied from KXErrorHandler and modified to explicitly use known extensions
|
||||
static QByteArray errorMessage( const XErrorEvent& event, Display* dpy )
|
||||
{ // "Error: <error> (<value>), Request: <request>(<value>), Resource: <value>"
|
||||
{
|
||||
QByteArray ret;
|
||||
char tmp[ 256 ];
|
||||
char num[ 256 ];
|
||||
if( event.request_code < 128 ) // core request
|
||||
{
|
||||
char tmp[256];
|
||||
char num[256];
|
||||
if( event.request_code < 128 )
|
||||
{ // Core request
|
||||
XGetErrorText( dpy, event.error_code, tmp, 255 );
|
||||
if( char* paren = strchr( tmp, '(' )) // the explanation in parentheses just makes
|
||||
*paren = '\0'; // it more verbose and is not really useful
|
||||
// the various casts are to get overloads non-ambiguous :-/
|
||||
ret = QByteArray( "error: " ) + (const char*)tmp + '[' + QByteArray::number( event.error_code ) + ']';
|
||||
// The explanation in parentheses just makes
|
||||
// it more verbose and is not really useful
|
||||
if( char* paren = strchr( tmp, '(' ))
|
||||
*paren = '\0';
|
||||
// The various casts are to get overloads non-ambiguous :-/
|
||||
ret = QByteArray( "error: " ) + (const char*)( tmp ) + '[' + QByteArray::number( event.error_code ) + ']';
|
||||
sprintf( num, "%d", event.request_code );
|
||||
XGetErrorDatabaseText( dpy, "XRequest", num, "<unknown>", tmp, 256 );
|
||||
ret += QByteArray( ", request: " ) + (const char*)tmp + '[' + QByteArray::number( event.request_code ) + ']';
|
||||
ret += QByteArray( ", request: " ) + (const char*)( tmp ) + '[' + QByteArray::number( event.request_code ) + ']';
|
||||
if( event.resourceid != 0 )
|
||||
ret += QByteArray( ", resource: 0x" ) + QByteArray::number( (qlonglong)event.resourceid, 16 );
|
||||
ret += QByteArray( ", resource: 0x" ) + QByteArray::number( qlonglong( event.resourceid ), 16 );
|
||||
}
|
||||
else // extensions
|
||||
else // Extensions
|
||||
{
|
||||
// XGetErrorText() currently has a bug that makes it fail to find text
|
||||
// for some errors (when error==error_base), also XGetErrorDatabaseText()
|
||||
|
@ -103,7 +111,7 @@ static QByteArray errorMessage( const XErrorEvent& event, Display* dpy )
|
|||
// - Opening another X connection now can cause deadlock with server grabs.
|
||||
// - Fetching it at startup means a bunch of roundtrips.
|
||||
|
||||
// KWin here explicitly uses known extensions.
|
||||
// KWin here explicitly uses known extensions.
|
||||
int nextensions;
|
||||
const char** extensions;
|
||||
int* majors;
|
||||
|
@ -112,20 +120,18 @@ static QByteArray errorMessage( const XErrorEvent& event, Display* dpy )
|
|||
XGetErrorText( dpy, event.error_code, tmp, 255 );
|
||||
int index = -1;
|
||||
int base = 0;
|
||||
for( int i = 0;
|
||||
i < nextensions;
|
||||
++i )
|
||||
if( error_bases[ i ] != 0
|
||||
&& event.error_code >= error_bases[ i ] && ( index == -1 || error_bases[ i ] > base ))
|
||||
for( int i = 0; i < nextensions; ++i )
|
||||
if( error_bases[i] != 0 &&
|
||||
event.error_code >= error_bases[i] && ( index == -1 || error_bases[i] > base ))
|
||||
{
|
||||
index = i;
|
||||
base = error_bases[ i ];
|
||||
base = error_bases[i];
|
||||
}
|
||||
if( tmp == QString::number( event.error_code )) // XGetErrorText() failed,
|
||||
{ // or it has a bug that causes not finding all errors, check ourselves
|
||||
if( tmp == QString::number( event.error_code ))
|
||||
{ // XGetErrorText() failed or it has a bug that causes not finding all errors, check ourselves
|
||||
if( index != -1 )
|
||||
{
|
||||
snprintf( num, 255, "%s.%d", extensions[ index ], event.error_code - base );
|
||||
snprintf( num, 255, "%s.%d", extensions[index], event.error_code - base );
|
||||
XGetErrorDatabaseText( dpy, "XProtoError", num, "<unknown>", tmp, 255 );
|
||||
}
|
||||
else
|
||||
|
@ -134,76 +140,70 @@ static QByteArray errorMessage( const XErrorEvent& event, Display* dpy )
|
|||
if( char* paren = strchr( tmp, '(' ))
|
||||
*paren = '\0';
|
||||
if( index != -1 )
|
||||
ret = QByteArray( "error: " ) + (const char*)tmp + '[' + (const char*)extensions[ index ]
|
||||
+ '+' + QByteArray::number( event.error_code - base ) + ']';
|
||||
ret = QByteArray( "error: " ) + (const char*)( tmp ) + '[' + (const char*)( extensions[index] ) +
|
||||
'+' + QByteArray::number( event.error_code - base ) + ']';
|
||||
else
|
||||
ret = QByteArray( "error: " ) + (const char*)tmp + '[' + QByteArray::number( event.error_code ) + ']';
|
||||
tmp[ 0 ] = '\0';
|
||||
for( int i = 0;
|
||||
i < nextensions;
|
||||
++i )
|
||||
if( majors[ i ] == event.request_code )
|
||||
ret = QByteArray( "error: " ) + (const char*)( tmp ) + '[' + QByteArray::number( event.error_code ) + ']';
|
||||
tmp[0] = '\0';
|
||||
for( int i = 0; i < nextensions; ++i )
|
||||
if( majors[i] == event.request_code )
|
||||
{
|
||||
snprintf( num, 255, "%s.%d", extensions[ i ], event.minor_code );
|
||||
snprintf( num, 255, "%s.%d", extensions[i], event.minor_code );
|
||||
XGetErrorDatabaseText( dpy, "XRequest", num, "<unknown>", tmp, 255 );
|
||||
ret += QByteArray( ", request: " ) + (const char*)tmp + '[' + (const char*)extensions[ i ] + '+'
|
||||
+ QByteArray::number( event.minor_code ) + ']';
|
||||
ret += QByteArray( ", request: " ) + (const char*)( tmp ) + '[' +
|
||||
(const char*)( extensions[i] ) + '+' + QByteArray::number( event.minor_code ) + ']';
|
||||
}
|
||||
if( tmp[ 0 ] == '\0' ) // not found???
|
||||
if( tmp[0] == '\0' ) // Not found?
|
||||
ret += QByteArray( ", request <unknown> [" ) + QByteArray::number( event.request_code ) + ':'
|
||||
+ QByteArray::number( event.minor_code ) + ']';
|
||||
if( event.resourceid != 0 )
|
||||
ret += QByteArray( ", resource: 0x" ) + QByteArray::number( (qlonglong)event.resourceid, 16 );
|
||||
ret += QByteArray( ", resource: 0x" ) + QByteArray::number( qlonglong( event.resourceid ), 16 );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int x11ErrorHandler(Display *d, XErrorEvent *e)
|
||||
static int x11ErrorHandler( Display* d, XErrorEvent* e )
|
||||
{
|
||||
bool ignore_badwindow = true; //maybe temporary
|
||||
bool ignore_badwindow = true; // Might be temporary
|
||||
|
||||
if (initting &&
|
||||
(
|
||||
e->request_code == X_ChangeWindowAttributes
|
||||
|| e->request_code == X_GrabKey
|
||||
)
|
||||
&& (e->error_code == BadAccess))
|
||||
if( initting && ( e->request_code == X_ChangeWindowAttributes || e->request_code == X_GrabKey ) &&
|
||||
e->error_code == BadAccess )
|
||||
{
|
||||
fputs(i18n("kwin: it looks like there's already a window manager running. kwin not started.\n").toLocal8Bit(), stderr);
|
||||
fputs( i18n( "kwin: it looks like there's already a window manager running. kwin not started.\n" ).toLocal8Bit(), stderr );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ignore_badwindow && (e->error_code == BadWindow || e->error_code == BadColor))
|
||||
if( ignore_badwindow && ( e->error_code == BadWindow || e->error_code == BadColor ))
|
||||
return 0;
|
||||
|
||||
// fprintf( stderr, "kwin: X Error (%s)\n", KXErrorHandler::errorMessage( *e, d ).data());
|
||||
fprintf( stderr, "kwin: X Error (%s)\n", errorMessage( *e, d ).data());
|
||||
//fprintf( stderr, "kwin: X Error (%s)\n", KXErrorHandler::errorMessage( *e, d ).data());
|
||||
fprintf( stderr, "kwin: X Error (%s)\n", errorMessage( *e, d ).data() );
|
||||
|
||||
if( kwin_sync )
|
||||
fprintf( stderr, "%s\n", kBacktrace().toLocal8Bit().data());
|
||||
fprintf( stderr, "%s\n", kBacktrace().toLocal8Bit().data() );
|
||||
|
||||
if (initting)
|
||||
if( initting )
|
||||
{
|
||||
fputs(i18n("kwin: failure during initialization; aborting").toLocal8Bit(), stderr);
|
||||
exit(1);
|
||||
fputs( i18n( "kwin: failure during initialization; aborting").toLocal8Bit(), stderr );
|
||||
exit( 1 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
class AlternativeWMDialog : public KDialog
|
||||
{
|
||||
public:
|
||||
AlternativeWMDialog() : KDialog()
|
||||
{
|
||||
AlternativeWMDialog()
|
||||
: KDialog()
|
||||
{
|
||||
setButtons( KDialog::Ok | KDialog::Cancel );
|
||||
|
||||
QWidget* mainWidget = new QWidget( this );
|
||||
QVBoxLayout* layout = new QVBoxLayout( mainWidget );
|
||||
QString text = i18n("KWin is unstable.\n"
|
||||
"It seems to have crashed several times in a row.\n"
|
||||
"You can select another window manager to run:");
|
||||
QString text = i18n(
|
||||
"KWin is unstable.\n"
|
||||
"It seems to have crashed several times in a row.\n"
|
||||
"You can select another window manager to run:" );
|
||||
QLabel* textLabel = new QLabel( text, mainWidget );
|
||||
layout->addWidget( textLabel );
|
||||
wmList = new QComboBox( mainWidget );
|
||||
|
@ -215,20 +215,20 @@ class AlternativeWMDialog : public KDialog
|
|||
addWM( "fvwm2" );
|
||||
addWM( "kwin" );
|
||||
|
||||
setMainWidget(mainWidget);
|
||||
setMainWidget( mainWidget );
|
||||
|
||||
raise();
|
||||
centerOnScreen( this );
|
||||
}
|
||||
}
|
||||
|
||||
void addWM( const QString& wm )
|
||||
{
|
||||
// TODO: check if wm is installed
|
||||
if( !KStandardDirs::findExe( wm ).isEmpty() )
|
||||
{
|
||||
// TODO: Check if WM is installed
|
||||
if( !KStandardDirs::findExe( wm ).isEmpty() )
|
||||
wmList->addItem( wm );
|
||||
}
|
||||
}
|
||||
QString selectedWM() const { return wmList->currentText(); }
|
||||
QString selectedWM() const
|
||||
{ return wmList->currentText(); }
|
||||
|
||||
private:
|
||||
QComboBox* wmList;
|
||||
|
@ -236,97 +236,94 @@ class AlternativeWMDialog : public KDialog
|
|||
|
||||
int Application::crashes = 0;
|
||||
|
||||
Application::Application( )
|
||||
: KApplication( ), owner( screen_number )
|
||||
Application::Application()
|
||||
: KApplication()
|
||||
, owner( screen_number )
|
||||
{
|
||||
if( KCmdLineArgs::parsedArgs( "qt" )->isSet( "sync" ))
|
||||
{
|
||||
kwin_sync = true;
|
||||
XSynchronize( display(), True );
|
||||
kDebug(1212) << "Running KWin in sync mode";
|
||||
}
|
||||
{
|
||||
kwin_sync = true;
|
||||
XSynchronize( display(), True );
|
||||
kDebug( 1212 ) << "Running KWin in sync mode";
|
||||
}
|
||||
KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
|
||||
KSharedConfig::Ptr config = KGlobal::config();
|
||||
if (!config->isImmutable() && args->isSet("lock"))
|
||||
if( !config->isImmutable() && args->isSet( "lock" ))
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
#warning this shouldn not be necessary
|
||||
#endif
|
||||
//config->setReadOnly(true);
|
||||
//config->setReadOnly( true );
|
||||
config->reparseConfiguration();
|
||||
}
|
||||
|
||||
if (screen_number == -1)
|
||||
screen_number = DefaultScreen(display());
|
||||
if( screen_number == -1 )
|
||||
screen_number = DefaultScreen( display() );
|
||||
|
||||
if( !owner.claim( args->isSet( "replace" ), true ))
|
||||
{
|
||||
fputs(i18n("kwin: unable to claim manager selection, another wm running? (try using --replace)\n").toLocal8Bit(), stderr);
|
||||
::exit(1);
|
||||
fputs( i18n( "kwin: unable to claim manager selection, another wm running? (try using --replace)\n" ).toLocal8Bit(), stderr );
|
||||
::exit( 1 );
|
||||
}
|
||||
connect( &owner, SIGNAL( lostOwnership()), SLOT( lostSelection()));
|
||||
connect( &owner, SIGNAL( lostOwnership() ), SLOT( lostSelection() ));
|
||||
|
||||
KCrash::setEmergencySaveFunction( Application::crashHandler );
|
||||
crashes = args->getOption("crashes").toInt();
|
||||
if(crashes >= 4)
|
||||
{
|
||||
// Something has gone seriously wrong
|
||||
crashes = args->getOption( "crashes" ).toInt();
|
||||
if( crashes >= 4 )
|
||||
{ // Something has gone seriously wrong
|
||||
AlternativeWMDialog dialog;
|
||||
QString cmd = "kwin";
|
||||
if( dialog.exec() == QDialog::Accepted )
|
||||
{
|
||||
cmd = dialog.selectedWM();
|
||||
}
|
||||
else
|
||||
::exit(1);
|
||||
::exit( 1 );
|
||||
if( cmd.length() > 500 )
|
||||
{
|
||||
kDebug(1212) << "Command is too long, truncating";
|
||||
cmd = cmd.left(500);
|
||||
}
|
||||
kDebug(1212) << "Starting" << cmd << "and exiting";
|
||||
{
|
||||
kDebug( 1212 ) << "Command is too long, truncating";
|
||||
cmd = cmd.left( 500 );
|
||||
}
|
||||
kDebug( 1212 ) << "Starting" << cmd << "and exiting";
|
||||
char buf[1024];
|
||||
sprintf(buf, "%s &", cmd.toAscii().data());
|
||||
system(buf);
|
||||
::exit(1);
|
||||
}
|
||||
// Disable compositing if we have had too many crashes
|
||||
sprintf( buf, "%s &", cmd.toAscii().data() );
|
||||
system( buf );
|
||||
::exit( 1 );
|
||||
}
|
||||
if( crashes >= 2 )
|
||||
{
|
||||
kDebug(1212) << "Too many crashes recently, disabling compositing";
|
||||
{ // Disable compositing if we have had too many crashes
|
||||
kDebug( 1212 ) << "Too many crashes recently, disabling compositing";
|
||||
KConfigGroup compgroup( config, "Compositing" );
|
||||
compgroup.writeEntry( "Enabled", false );
|
||||
}
|
||||
}
|
||||
// Reset crashes count if we stay up for more that 15 seconds
|
||||
QTimer::singleShot( 15*1000, this, SLOT( resetCrashesCount() ));
|
||||
|
||||
// if there was already kwin running, it saved its configuration after loosing the selection -> reread
|
||||
// If KWin was already running it saved its configuration after loosing the selection -> Reread
|
||||
config->reparseConfiguration();
|
||||
|
||||
initting = true; // startup....
|
||||
initting = true; // Startup...
|
||||
|
||||
// install X11 error handler
|
||||
// Install X11 error handler
|
||||
XSetErrorHandler( x11ErrorHandler );
|
||||
|
||||
// check whether another windowmanager is running
|
||||
XSelectInput(display(), rootWindow(), SubstructureRedirectMask );
|
||||
syncX(); // trigger error now
|
||||
// Check whether another windowmanager is running
|
||||
XSelectInput( display(), rootWindow(), SubstructureRedirectMask );
|
||||
syncX(); // Trigger error now
|
||||
|
||||
atoms = new Atoms;
|
||||
|
||||
initting = false; // TODO
|
||||
|
||||
// This tries to detect compositing options and can use GLX. GLX problems
|
||||
// (X errors) shouldn't cause kwin to abort, so this is out of the
|
||||
// critical startup section where x errors cause kwin to abort.
|
||||
// (X errors) shouldn't cause kwin to abort, so this is out of the
|
||||
// critical startup section where x errors cause kwin to abort.
|
||||
options = new Options;
|
||||
|
||||
// create workspace.
|
||||
(void) new Workspace( isSessionRestored() );
|
||||
|
||||
syncX(); // trigger possible errors, there's still a chance to abort
|
||||
syncX(); // Trigger possible errors, there's still a chance to abort
|
||||
|
||||
initting = false; // startup done, we are up and running now.
|
||||
initting = false; // Startup done, we are up and running now.
|
||||
|
||||
XEvent e;
|
||||
e.xclient.type = ClientMessage;
|
||||
|
@ -341,7 +338,7 @@ Application::Application( )
|
|||
Application::~Application()
|
||||
{
|
||||
delete Workspace::self();
|
||||
if( owner.ownerWindow() != None ) // if there was no --replace (no new WM)
|
||||
if( owner.ownerWindow() != None ) // If there was no --replace (no new WM)
|
||||
XSetInputFocus( display(), PointerRoot, RevertToPointerRoot, xTime() );
|
||||
delete options;
|
||||
delete effects;
|
||||
|
@ -352,15 +349,15 @@ void Application::lostSelection()
|
|||
{
|
||||
sendPostedEvents();
|
||||
delete Workspace::self();
|
||||
// remove windowmanager privileges
|
||||
XSelectInput(display(), rootWindow(), PropertyChangeMask );
|
||||
// Remove windowmanager privileges
|
||||
XSelectInput( display(), rootWindow(), PropertyChangeMask );
|
||||
quit();
|
||||
}
|
||||
|
||||
bool Application::x11EventFilter( XEvent *e )
|
||||
bool Application::x11EventFilter( XEvent* e )
|
||||
{
|
||||
if ( Workspace::self() && Workspace::self()->workspaceEvent( e ) )
|
||||
return true;
|
||||
if( Workspace::self() && Workspace::self()->workspaceEvent( e ))
|
||||
return true;
|
||||
return KApplication::x11EventFilter( e );
|
||||
}
|
||||
|
||||
|
@ -371,12 +368,12 @@ bool Application::notify( QObject* o, QEvent* e )
|
|||
return KApplication::notify( o, e );
|
||||
}
|
||||
|
||||
static void sighandler(int)
|
||||
static void sighandler( int )
|
||||
{
|
||||
QApplication::exit();
|
||||
}
|
||||
|
||||
void Application::crashHandler(int signal)
|
||||
void Application::crashHandler( int signal )
|
||||
{
|
||||
crashes++;
|
||||
|
||||
|
@ -393,7 +390,6 @@ void Application::resetCrashesCount()
|
|||
crashes = 0;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
static const char version[] = KDE_VERSION_STRING;
|
||||
|
@ -403,99 +399,103 @@ extern "C"
|
|||
KDE_EXPORT int kdemain( int argc, char * argv[] )
|
||||
{
|
||||
bool restored = false;
|
||||
for (int arg = 1; arg < argc; arg++)
|
||||
for( int arg = 1; arg < argc; arg++ )
|
||||
{
|
||||
if (! qstrcmp(argv[arg], "-session"))
|
||||
if( !qstrcmp( argv[arg], "-session" ))
|
||||
{
|
||||
restored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! restored)
|
||||
{
|
||||
// we only do the multihead fork if we are not restored by the session
|
||||
// manager, since the session manager will register multiple kwins,
|
||||
// one for each screen...
|
||||
QByteArray multiHead = getenv("KDE_MULTIHEAD");
|
||||
if (multiHead.toLower() == "true")
|
||||
if( !restored )
|
||||
{ // We only do the multihead fork if we are not restored by the session
|
||||
// manager, since the session manager will register multiple kwins,
|
||||
// one for each screen...
|
||||
QByteArray multiHead = getenv( "KDE_MULTIHEAD" );
|
||||
if( multiHead.toLower() == "true" )
|
||||
{
|
||||
|
||||
Display* dpy = XOpenDisplay( NULL );
|
||||
if ( !dpy )
|
||||
if( !dpy )
|
||||
{
|
||||
fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
|
||||
argv[0], XDisplayName(NULL ) );
|
||||
exit (1);
|
||||
fprintf( stderr, "%s: FATAL ERROR while trying to open display %s\n",
|
||||
argv[0], XDisplayName( NULL ));
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
int number_of_screens = ScreenCount( dpy );
|
||||
KWin::screen_number = DefaultScreen( dpy );
|
||||
int pos; // temporarily needed to reconstruct DISPLAY var if multi-head
|
||||
int pos; // Temporarily needed to reconstruct DISPLAY var if multi-head
|
||||
QByteArray display_name = XDisplayString( dpy );
|
||||
XCloseDisplay( dpy );
|
||||
dpy = 0;
|
||||
|
||||
if ((pos = display_name.lastIndexOf('.')) != -1 )
|
||||
display_name.remove(pos,10); // 10 is enough to be sure we removed ".s"
|
||||
if(( pos = display_name.lastIndexOf( '.' )) != -1 )
|
||||
display_name.remove( pos, 10 ); // 10 is enough to be sure we removed ".s"
|
||||
|
||||
QString envir;
|
||||
if (number_of_screens != 1)
|
||||
if( number_of_screens != 1 )
|
||||
{
|
||||
for (int i = 0; i < number_of_screens; i++ )
|
||||
for( int i = 0; i < number_of_screens; i++ )
|
||||
{
|
||||
// if execution doesn't pass by here, then kwin
|
||||
// acts exactly as previously
|
||||
if ( i != KWin::screen_number && fork() == 0 )
|
||||
// If execution doesn't pass by here, then kwin
|
||||
// acts exactly as previously
|
||||
if( i != KWin::screen_number && fork() == 0 )
|
||||
{
|
||||
KWin::screen_number = i;
|
||||
// break here because we are the child process, we don't
|
||||
// want to fork() anymore
|
||||
// Break here because we are the child process, we don't
|
||||
// want to fork() anymore
|
||||
break;
|
||||
}
|
||||
}
|
||||
// in the next statement, display_name shouldn't contain a screen
|
||||
// number. If it had it, it was removed at the "pos" check
|
||||
envir.sprintf("DISPLAY=%s.%d", display_name.data(), KWin::screen_number);
|
||||
// In the next statement, display_name shouldn't contain a screen
|
||||
// number. If it had it, it was removed at the "pos" check
|
||||
envir.sprintf( "DISPLAY=%s.%d", display_name.data(), KWin::screen_number );
|
||||
|
||||
if (putenv( strdup(envir.toAscii())) )
|
||||
if( putenv( strdup( envir.toAscii() )))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: WARNING: unable to set DISPLAY environment variable\n",
|
||||
argv[0]);
|
||||
fprintf( stderr, "%s: WARNING: unable to set DISPLAY environment variable\n", argv[0] );
|
||||
perror("putenv()");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KAboutData aboutData( "kwin", 0, ki18n("KWin"),
|
||||
version, ki18n(description), KAboutData::License_GPL,
|
||||
ki18n("(c) 1999-2005, The KDE Developers"));
|
||||
aboutData.addAuthor(ki18n("Matthias Ettrich"),KLocalizedString(), "ettrich@kde.org");
|
||||
aboutData.addAuthor(ki18n("Cristian Tibirna"),KLocalizedString(), "tibirna@kde.org");
|
||||
aboutData.addAuthor(ki18n("Daniel M. Duley"),KLocalizedString(), "mosfet@kde.org");
|
||||
aboutData.addAuthor(ki18n("Luboš Luňák"), ki18n( "Maintainer" ), "l.lunak@kde.org");
|
||||
KAboutData aboutData(
|
||||
"kwin", // The program name used internally
|
||||
0, // The message catalog name. If null, program name is used instead
|
||||
ki18n( "KWin" ), // A displayable program name string
|
||||
version, // The program version string
|
||||
ki18n( description ), // Short description of what the app does
|
||||
KAboutData::License_GPL, // The license this code is released under
|
||||
ki18n( "(c) 1999-2008, The KDE Developers" )); // Copyright Statement
|
||||
aboutData.addAuthor( ki18n( "Matthias Ettrich" ),KLocalizedString(), "ettrich@kde.org" );
|
||||
aboutData.addAuthor( ki18n( "Cristian Tibirna" ),KLocalizedString(), "tibirna@kde.org" );
|
||||
aboutData.addAuthor( ki18n( "Daniel M. Duley" ),KLocalizedString(), "mosfet@kde.org" );
|
||||
aboutData.addAuthor( ki18n( "Luboš Luňák" ), ki18n( "Maintainer" ), "l.lunak@kde.org" );
|
||||
|
||||
KCmdLineArgs::init(argc, argv, &aboutData);
|
||||
KCmdLineArgs::init( argc, argv, &aboutData );
|
||||
|
||||
KCmdLineOptions args;
|
||||
args.add("lock", ki18n("Disable configuration options"));
|
||||
args.add("replace", ki18n("Replace already-running ICCCM2.0-compliant window manager"));
|
||||
args.add("crashes <n>", ki18n("Indicate that KWin has recently crashed n times"));
|
||||
args.add( "lock", ki18n( "Disable configuration options" ));
|
||||
args.add( "replace", ki18n( "Replace already-running ICCCM2.0-compliant window manager" ));
|
||||
args.add( "crashes <n>", ki18n( "Indicate that KWin has recently crashed n times" ));
|
||||
KCmdLineArgs::addCmdLineOptions( args );
|
||||
|
||||
if (signal(SIGTERM, KWin::sighandler) == SIG_IGN)
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
if (signal(SIGINT, KWin::sighandler) == SIG_IGN)
|
||||
signal(SIGINT, SIG_IGN);
|
||||
if (signal(SIGHUP, KWin::sighandler) == SIG_IGN)
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
// HACK this is needed for AIGLX
|
||||
if( signal( SIGTERM, KWin::sighandler ) == SIG_IGN )
|
||||
signal( SIGTERM, SIG_IGN );
|
||||
if( signal( SIGINT, KWin::sighandler ) == SIG_IGN )
|
||||
signal( SIGINT, SIG_IGN );
|
||||
if( signal( SIGHUP, KWin::sighandler ) == SIG_IGN )
|
||||
signal( SIGHUP, SIG_IGN );
|
||||
|
||||
// HACK: This is needed for AIGLX
|
||||
if( qstrcmp( getenv( "KWIN_DIRECT_GL" ), "1" ) != 0 )
|
||||
setenv( "LIBGL_ALWAYS_INDIRECT","1", true );
|
||||
// HACK this is needed to work around a Qt4.4.0RC1 bug (#157659)
|
||||
|
||||
// HACK: this is needed to work around a Qt4.4.0RC1 bug (#157659)
|
||||
setenv( "QT_SLOW_TOPLEVEL_RESIZE", "1", true );
|
||||
|
||||
KWin::Application a;
|
||||
KWin::SessionManager weAreIndeed;
|
||||
KWin::SessionSaveDoneHelper helper;
|
||||
|
@ -505,15 +505,16 @@ KDE_EXPORT int kdemain( int argc, char * argv[] )
|
|||
if( qstrcmp( getenv( "KWIN_DIRECT_GL" ), "1" ) == 0 )
|
||||
kDebug( 1212 ) << "KWIN_DIRECT_GL set, not forcing LIBGL_ALWAYS_INDIRECT=1";
|
||||
|
||||
fcntl(XConnectionNumber(KWin::display()), F_SETFD, 1);
|
||||
fcntl( XConnectionNumber( KWin::display() ), F_SETFD, 1 );
|
||||
|
||||
QString appname;
|
||||
if (KWin::screen_number == 0)
|
||||
if( KWin::screen_number == 0 )
|
||||
appname = "org.kde.kwin";
|
||||
else
|
||||
appname.sprintf("org.kde.kwin-screen-%d", KWin::screen_number);
|
||||
appname.sprintf( "org.kde.kwin-screen-%d", KWin::screen_number );
|
||||
|
||||
QDBusConnection::sessionBus().interface()->registerService( appname, QDBusConnectionInterface::DontQueueService );
|
||||
QDBusConnection::sessionBus().interface()->registerService(
|
||||
appname, QDBusConnectionInterface::DontQueueService );
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
|
5
main.h
5
main.h
|
@ -37,9 +37,10 @@ class Application : public KApplication
|
|||
~Application();
|
||||
|
||||
protected:
|
||||
bool x11EventFilter( XEvent * );
|
||||
bool x11EventFilter( XEvent* );
|
||||
bool notify( QObject* o, QEvent* e );
|
||||
static void crashHandler(int signal);
|
||||
static void crashHandler( int signal );
|
||||
|
||||
private slots:
|
||||
void lostSelection();
|
||||
void resetCrashesCount();
|
||||
|
|
422
manage.cpp
422
manage.cpp
|
@ -19,11 +19,7 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
This file contains things relevant to handling incoming events.
|
||||
|
||||
*/
|
||||
// This file contains things relevant to handling incoming events.
|
||||
|
||||
#include "client.h"
|
||||
|
||||
|
@ -39,46 +35,46 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
/*!
|
||||
Manages the clients. This means handling the very first maprequest:
|
||||
reparenting, initial geometry, initial state, placement, etc.
|
||||
Returns false if KWin is not going to manage this window.
|
||||
/**
|
||||
* Manages the clients. This means handling the very first maprequest:
|
||||
* reparenting, initial geometry, initial state, placement, etc.
|
||||
* Returns false if KWin is not going to manage this window.
|
||||
*/
|
||||
bool Client::manage( Window w, bool isMapped )
|
||||
{
|
||||
StackingUpdatesBlocker stacking_blocker( workspace());
|
||||
StackingUpdatesBlocker stacking_blocker( workspace() );
|
||||
|
||||
grabXServer();
|
||||
|
||||
XWindowAttributes attr;
|
||||
if( !XGetWindowAttributes(display(), w, &attr))
|
||||
if( !XGetWindowAttributes( display(), w, &attr ))
|
||||
{
|
||||
ungrabXServer();
|
||||
return false;
|
||||
}
|
||||
|
||||
// from this place on, manage() mustn't return false
|
||||
// From this place on, manage() must not return false
|
||||
block_geometry_updates = 1;
|
||||
pending_geometry_update = PendingGeometryForced; // force update when finishing with geometry changes
|
||||
pending_geometry_update = PendingGeometryForced; // Force update when finishing with geometry changes
|
||||
|
||||
embedClient( w, attr );
|
||||
|
||||
|
||||
vis = attr.visual;
|
||||
bit_depth = attr.depth;
|
||||
|
||||
// SELI order all these things in some sane manner
|
||||
// SELI TODO: Order all these things in some sane manner
|
||||
|
||||
bool init_minimize = false;
|
||||
XWMHints * hints = XGetWMHints(display(), w );
|
||||
if (hints && (hints->flags & StateHint) && hints->initial_state == IconicState)
|
||||
XWMHints* hints = XGetWMHints( display(), w );
|
||||
if( hints && ( hints->flags & StateHint ) && hints->initial_state == IconicState )
|
||||
init_minimize = true;
|
||||
if (hints)
|
||||
XFree(hints);
|
||||
if( hints )
|
||||
XFree( hints );
|
||||
if( isMapped )
|
||||
init_minimize = false; // if it's already mapped, ignore hint
|
||||
init_minimize = false; // If it's already mapped, ignore hint
|
||||
|
||||
unsigned long properties[ 2 ];
|
||||
properties[ WinInfo::PROTOCOLS ] =
|
||||
unsigned long properties[2];
|
||||
properties[WinInfo::PROTOCOLS] =
|
||||
NET::WMDesktop |
|
||||
NET::WMState |
|
||||
NET::WMWindowType |
|
||||
|
@ -89,7 +85,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
NET::WMPid |
|
||||
NET::WMIconName |
|
||||
0;
|
||||
properties[ WinInfo::PROTOCOLS2 ] =
|
||||
properties[WinInfo::PROTOCOLS2] =
|
||||
NET::WM2UserTime |
|
||||
NET::WM2StartupId |
|
||||
NET::WM2ExtendedStrut |
|
||||
|
@ -106,31 +102,31 @@ bool Client::manage( Window w, bool isMapped )
|
|||
getWmClientLeader();
|
||||
getWmClientMachine();
|
||||
getSyncCounter();
|
||||
// first only read the caption text, so that setupWindowRules() can use it for matching,
|
||||
// First only read the caption text, so that setupWindowRules() can use it for matching,
|
||||
// and only then really set the caption using setCaption(), which checks for duplicates etc.
|
||||
// and also relies on rules already existing
|
||||
cap_normal = readName();
|
||||
setupWindowRules( false );
|
||||
ignore_focus_stealing = options->checkIgnoreFocusStealing( this ); // TODO change to rules
|
||||
ignore_focus_stealing = options->checkIgnoreFocusStealing( this ); // TODO: Change to rules
|
||||
setCaption( cap_normal, true );
|
||||
|
||||
if( Extensions::shapeAvailable())
|
||||
if( Extensions::shapeAvailable() )
|
||||
XShapeSelectInput( display(), window(), ShapeNotifyMask );
|
||||
detectShape( window());
|
||||
detectShape( window() );
|
||||
detectNoBorder();
|
||||
fetchIconicName();
|
||||
getWMHints(); // needs to be done before readTransient() because of reading the group
|
||||
modal = ( info->state() & NET::Modal ) != 0; // needs to be valid before handling groups
|
||||
getWMHints(); // Needs to be done before readTransient() because of reading the group
|
||||
modal = ( info->state() & NET::Modal ) != 0; // Needs to be valid before handling groups
|
||||
readTransient();
|
||||
getIcons();
|
||||
getWindowProtocols();
|
||||
getWmNormalHints(); // get xSizeHint
|
||||
getWmNormalHints(); // Get xSizeHint
|
||||
getMotifHints();
|
||||
|
||||
// TODO try to obey all state information from info->state()
|
||||
// TODO: Try to obey all state information from info->state()
|
||||
|
||||
original_skip_taskbar = skip_taskbar = ( info->state() & NET::SkipTaskbar) != 0;
|
||||
skip_pager = ( info->state() & NET::SkipPager) != 0;
|
||||
original_skip_taskbar = skip_taskbar = ( info->state() & NET::SkipTaskbar ) != 0;
|
||||
skip_pager = ( info->state() & NET::SkipPager ) != 0;
|
||||
|
||||
setupCompositing();
|
||||
|
||||
|
@ -151,9 +147,9 @@ bool Client::manage( Window w, bool isMapped )
|
|||
|
||||
init_minimize = rules()->checkMinimize( init_minimize, !isMapped );
|
||||
noborder = rules()->checkNoBorder( noborder, !isMapped );
|
||||
|
||||
// initial desktop placement
|
||||
if ( session )
|
||||
|
||||
// Initial desktop placement
|
||||
if( session )
|
||||
{
|
||||
desk = session->desktop;
|
||||
if( session->onAllDesktops )
|
||||
|
@ -161,23 +157,23 @@ bool Client::manage( Window w, bool isMapped )
|
|||
}
|
||||
else
|
||||
{
|
||||
// if this window is transient, ensure that it is opened on the
|
||||
// If this window is transient, ensure that it is opened on the
|
||||
// same window as its parent. this is necessary when an application
|
||||
// starts up on a different desktop than is currently displayed
|
||||
if( isTransient())
|
||||
if( isTransient() )
|
||||
{
|
||||
ClientList mainclients = mainClients();
|
||||
bool on_current = false;
|
||||
Client* maincl = NULL;
|
||||
// this is slightly duplicated from Placement::placeOnMainWindow()
|
||||
// This is slightly duplicated from Placement::placeOnMainWindow()
|
||||
for( ClientList::ConstIterator it = mainclients.constBegin();
|
||||
it != mainclients.constEnd();
|
||||
++it )
|
||||
it != mainclients.constEnd();
|
||||
++it )
|
||||
{
|
||||
if( mainclients.count() > 1 && (*it)->isSpecialWindow())
|
||||
continue; // don't consider toolbars etc when placing
|
||||
if( mainclients.count() > 1 && (*it)->isSpecialWindow() )
|
||||
continue; // Don't consider toolbars etc when placing
|
||||
maincl = *it;
|
||||
if( (*it)->isOnCurrentDesktop())
|
||||
if( (*it)->isOnCurrentDesktop() )
|
||||
on_current = true;
|
||||
}
|
||||
if( on_current )
|
||||
|
@ -185,19 +181,19 @@ bool Client::manage( Window w, bool isMapped )
|
|||
else if( maincl != NULL )
|
||||
desk = maincl->desktop();
|
||||
}
|
||||
if ( info->desktop() )
|
||||
desk = info->desktop(); // window had the initial desktop property, force it
|
||||
if( info->desktop() )
|
||||
desk = info->desktop(); // Window had the initial desktop property, force it
|
||||
if( desktop() == 0 && asn_valid && asn_data.desktop() != 0 )
|
||||
desk = asn_data.desktop();
|
||||
}
|
||||
if ( desk == 0 ) // assume window wants to be visible on the current desktop
|
||||
if( desk == 0 ) // Assume window wants to be visible on the current desktop
|
||||
desk = workspace()->currentDesktop();
|
||||
desk = rules()->checkDesktop( desk, !isMapped );
|
||||
if( desk != NET::OnAllDesktops ) // do range check
|
||||
if( desk != NET::OnAllDesktops ) // Do range check
|
||||
desk = qMax( 1, qMin( workspace()->numberOfDesktops(), desk ));
|
||||
info->setDesktop( desk );
|
||||
workspace()->updateOnAllDesktopsOfTransients( this ); // SELI
|
||||
// onAllDesktopsChange(); decoration doesn't exist here yet
|
||||
workspace()->updateOnAllDesktopsOfTransients( this ); // SELI TODO
|
||||
//onAllDesktopsChange(); // Decoration doesn't exist here yet
|
||||
|
||||
QRect geom( attr.x, attr.y, attr.width, attr.height );
|
||||
bool placementDone = false;
|
||||
|
@ -208,48 +204,45 @@ bool Client::manage( Window w, bool isMapped )
|
|||
QRect area;
|
||||
bool partial_keep_in_area = isMapped || session;
|
||||
if( isMapped || session )
|
||||
area = workspace()->clientArea( FullArea, geom.center(), desktop());
|
||||
area = workspace()->clientArea( FullArea, geom.center(), desktop() );
|
||||
else if( options->xineramaPlacementEnabled )
|
||||
{
|
||||
int screen = options->xineramaPlacementScreen;
|
||||
if( screen == -1 ) // active screen
|
||||
if( screen == -1 ) // Active screen
|
||||
screen = asn_data.xinerama() == -1 ? workspace()->activeScreen() : asn_data.xinerama();
|
||||
area = workspace()->clientArea( PlacementArea, workspace()->screenGeometry( screen ).center(), desktop());
|
||||
}
|
||||
else
|
||||
area = workspace()->clientArea( PlacementArea, cursorPos(), desktop());
|
||||
area = workspace()->clientArea( PlacementArea, cursorPos(), desktop() );
|
||||
|
||||
if( int type = checkFullScreenHack( geom ))
|
||||
{
|
||||
fullscreen_mode = FullScreenHack;
|
||||
if( rules()->checkStrictGeometry( false ))
|
||||
{
|
||||
geom = type == 2 // 1 - it's xinerama-aware fullscreen hack, 2 - it's full area
|
||||
? workspace()->clientArea( FullArea, geom.center(), desktop())
|
||||
: workspace()->clientArea( ScreenArea, geom.center(), desktop());
|
||||
geom = type == 2 // 1 = It's xinerama-aware fullscreen hack, 2 = It's full area
|
||||
? workspace()->clientArea( FullArea, geom.center(), desktop() )
|
||||
: workspace()->clientArea( ScreenArea, geom.center(), desktop() );
|
||||
}
|
||||
else
|
||||
geom = workspace()->clientArea( FullScreenArea, geom.center(), desktop());
|
||||
geom = workspace()->clientArea( FullScreenArea, geom.center(), desktop() );
|
||||
placementDone = true;
|
||||
}
|
||||
|
||||
if ( isDesktop() )
|
||||
{
|
||||
// kwin doesn't manage desktop windows
|
||||
if( isDesktop() )
|
||||
// KWin doesn't manage desktop windows
|
||||
placementDone = true;
|
||||
}
|
||||
|
||||
bool usePosition = false;
|
||||
if ( isMapped || session || placementDone )
|
||||
placementDone = true; // use geometry
|
||||
else if( isTransient() && !isUtility() && !isDialog() && !isSplash())
|
||||
placementDone = true; // Use geometry
|
||||
else if( isTransient() && !isUtility() && !isDialog() && !isSplash() )
|
||||
usePosition = true;
|
||||
else if( isTransient() && !hasNETSupport())
|
||||
else if( isTransient() && !hasNETSupport() )
|
||||
usePosition = true;
|
||||
else if( isDialog() && hasNETSupport())
|
||||
// if the dialog is actually non-NETWM transient window, don't try to apply placement to it,
|
||||
// it breaks with too many things (xmms, display)
|
||||
{
|
||||
else if( isDialog() && hasNETSupport() )
|
||||
{ // If the dialog is actually non-NETWM transient window, don't try to apply placement to it,
|
||||
// it breaks with too many things (xmms, display)
|
||||
if( mainClients().count() >= 1 )
|
||||
{
|
||||
#if 1
|
||||
|
@ -261,96 +254,94 @@ bool Client::manage( Window w, bool isMapped )
|
|||
// there's also _NET_WM_FULL_PLACEMENT.
|
||||
usePosition = true;
|
||||
#else
|
||||
; // force using placement policy
|
||||
; // Force using placement policy
|
||||
#endif
|
||||
}
|
||||
else
|
||||
usePosition = true;
|
||||
}
|
||||
else if( isSplash())
|
||||
; // force using placement policy
|
||||
else if( isSplash() )
|
||||
; // Force using placement policy
|
||||
else
|
||||
usePosition = true;
|
||||
if( !rules()->checkIgnoreGeometry( !usePosition ))
|
||||
{
|
||||
bool ignorePPosition = ( options->ignorePositionClasses.contains(QString::fromLatin1(resourceClass())));
|
||||
bool ignorePPosition = options->ignorePositionClasses.contains(
|
||||
QString::fromLatin1( resourceClass() ));
|
||||
|
||||
if ( ( (xSizeHint.flags & PPosition) && !ignorePPosition ) ||
|
||||
(xSizeHint.flags & USPosition) )
|
||||
if((( xSizeHint.flags & PPosition ) && !ignorePPosition ) ||
|
||||
( xSizeHint.flags & USPosition ))
|
||||
{
|
||||
placementDone = true;
|
||||
// disobey xinerama placement option for now (#70943)
|
||||
area = workspace()->clientArea( PlacementArea, geom.center(), desktop());
|
||||
// Disobey xinerama placement option for now (#70943)
|
||||
area = workspace()->clientArea( PlacementArea, geom.center(), desktop() );
|
||||
}
|
||||
}
|
||||
if( true ) // size is always obeyed for now, only with constraints applied
|
||||
if ( (xSizeHint.flags & USSize) || (xSizeHint.flags & PSize) )
|
||||
{
|
||||
// keep in mind that we now actually have a size :-)
|
||||
}
|
||||
//if( true ) // Size is always obeyed for now, only with constraints applied
|
||||
// if(( xSizeHint.flags & USSize ) || ( xSizeHint.flags & PSize ))
|
||||
// {
|
||||
// // Keep in mind that we now actually have a size :-)
|
||||
// }
|
||||
|
||||
if (xSizeHint.flags & PMaxSize)
|
||||
if( xSizeHint.flags & PMaxSize )
|
||||
geom.setSize( geom.size().boundedTo(
|
||||
rules()->checkMaxSize( QSize(xSizeHint.max_width, xSizeHint.max_height ) ) ) );
|
||||
if (xSizeHint.flags & PMinSize)
|
||||
rules()->checkMaxSize( QSize( xSizeHint.max_width, xSizeHint.max_height ))));
|
||||
if( xSizeHint.flags & PMinSize )
|
||||
geom.setSize( geom.size().expandedTo(
|
||||
rules()->checkMinSize( QSize(xSizeHint.min_width, xSizeHint.min_height ) ) ) );
|
||||
rules()->checkMinSize( QSize( xSizeHint.min_width, xSizeHint.min_height ))));
|
||||
|
||||
if( isMovable())
|
||||
{
|
||||
if( geom.x() > area.right() || geom.y() > area.bottom())
|
||||
placementDone = false; // weird, do not trust.
|
||||
}
|
||||
if( isMovable() && ( geom.x() > area.right() || geom.y() > area.bottom() ))
|
||||
placementDone = false; // Weird, do not trust.
|
||||
|
||||
if ( placementDone )
|
||||
move( geom.x(), geom.y() ); // before gravitating
|
||||
if( placementDone )
|
||||
move( geom.x(), geom.y() ); // Before gravitating
|
||||
|
||||
updateDecoration( false ); // also gravitates
|
||||
// TODO is CentralGravity right here, when resizing is done after gravitating?
|
||||
plainResize( rules()->checkSize( sizeForClientSize( geom.size()), !isMapped ));
|
||||
updateDecoration( false ); // Also gravitates
|
||||
// TODO: Is CentralGravity right here, when resizing is done after gravitating?
|
||||
plainResize( rules()->checkSize( sizeForClientSize( geom.size() ), !isMapped ));
|
||||
|
||||
QPoint forced_pos = rules()->checkPosition( invalidPoint, !isMapped );
|
||||
if( forced_pos != invalidPoint )
|
||||
{
|
||||
move( forced_pos );
|
||||
placementDone = true;
|
||||
// don't keep inside workarea if the window has specially configured position
|
||||
// Don't keep inside workarea if the window has specially configured position
|
||||
partial_keep_in_area = true;
|
||||
area = workspace()->clientArea( FullArea, geom.center(), desktop());
|
||||
area = workspace()->clientArea( FullArea, geom.center(), desktop() );
|
||||
}
|
||||
if( !placementDone )
|
||||
{ // placement needs to be after setting size
|
||||
if( !placementDone )
|
||||
{ // Placement needs to be after setting size
|
||||
workspace()->place( this, area );
|
||||
placementDone = true;
|
||||
}
|
||||
|
||||
if(( !isSpecialWindow() || isToolbar()) && isMovable())
|
||||
if(( !isSpecialWindow() || isToolbar() ) && isMovable() )
|
||||
keepInArea( area, partial_keep_in_area );
|
||||
|
||||
updateShape();
|
||||
|
||||
//CT extra check for stupid jdk 1.3.1. But should make sense in general
|
||||
|
||||
// CT: Extra check for stupid jdk 1.3.1. But should make sense in general
|
||||
// if client has initial state set to Iconic and is transient with a parent
|
||||
// window that is not Iconic, set init_state to Normal
|
||||
if( init_minimize && isTransient())
|
||||
if( init_minimize && isTransient() )
|
||||
{
|
||||
ClientList mainclients = mainClients();
|
||||
for( ClientList::ConstIterator it = mainclients.constBegin();
|
||||
it != mainclients.constEnd();
|
||||
++it )
|
||||
it != mainclients.constEnd();
|
||||
++it )
|
||||
if( (*it)->isShown( true ))
|
||||
init_minimize = false; // SELI even e.g. for NET::Utility?
|
||||
init_minimize = false; // SELI TODO: Even e.g. for NET::Utility?
|
||||
}
|
||||
// if a dialog is shown for minimized window, minimize it too
|
||||
// If a dialog is shown for minimized window, minimize it too
|
||||
if( !init_minimize && isTransient() && mainClients().count() > 0 )
|
||||
{
|
||||
bool visible_parent = false;
|
||||
// use allMainClients(), to include also main clients of group transients
|
||||
// Use allMainClients(), to include also main clients of group transients
|
||||
// that have been optimized out in Client::checkGroupTransients()
|
||||
ClientList mainclients = allMainClients();
|
||||
for( ClientList::ConstIterator it = mainclients.constBegin();
|
||||
it != mainclients.constEnd();
|
||||
++it )
|
||||
it != mainclients.constEnd();
|
||||
++it )
|
||||
if( (*it)->isShown( true ))
|
||||
visible_parent = true;
|
||||
if( !visible_parent )
|
||||
|
@ -361,19 +352,19 @@ bool Client::manage( Window w, bool isMapped )
|
|||
}
|
||||
|
||||
if( init_minimize )
|
||||
minimize( true ); // no animation
|
||||
minimize( true ); // No animation
|
||||
|
||||
// SELI this seems to be mainly for kstart and ksystraycmd
|
||||
// SELI TODO: This seems to be mainly for kstart and ksystraycmd
|
||||
// probably should be replaced by something better
|
||||
bool doNotShow = false;
|
||||
if ( workspace()->isNotManaged( caption() ) )
|
||||
if ( workspace()->isNotManaged( caption() ))
|
||||
doNotShow = true;
|
||||
|
||||
// other settings from the previous session
|
||||
if ( session )
|
||||
// Other settings from the previous session
|
||||
if( session )
|
||||
{
|
||||
// session restored windows are not considered to be new windows WRT rules,
|
||||
// i.e. obey only forcing rules
|
||||
// Session restored windows are not considered to be new windows WRT rules,
|
||||
// I.e. obey only forcing rules
|
||||
setKeepAbove( session->keepAbove );
|
||||
setKeepBelow( session->keepBelow );
|
||||
setSkipTaskbar( session->skipTaskbar, true );
|
||||
|
@ -381,59 +372,59 @@ bool Client::manage( Window w, bool isMapped )
|
|||
setShade( session->shaded ? ShadeNormal : ShadeNone );
|
||||
if( session->maximized != MaximizeRestore )
|
||||
{
|
||||
maximize( (MaximizeMode) session->maximized );
|
||||
maximize( MaximizeMode( session->maximized ));
|
||||
geom_restore = session->restore;
|
||||
}
|
||||
if( session->fullscreen == FullScreenHack )
|
||||
; // nothing, this should be already set again above
|
||||
; // Nothing, this should be already set again above
|
||||
else if( session->fullscreen != FullScreenNone )
|
||||
{
|
||||
setFullScreen( true, false );
|
||||
geom_fs_restore = session->fsrestore;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
geom_restore = geometry(); // remember restore geometry
|
||||
if ( isMaximizable()
|
||||
&& ( width() >= area.width() || height() >= area.height() ) )
|
||||
{
|
||||
// window is too large for the screen, maximize in the
|
||||
// directions necessary
|
||||
if ( width() >= area.width() && height() >= area.height() )
|
||||
geom_restore = geometry(); // Remember restore geometry
|
||||
if( isMaximizable() && ( width() >= area.width() || height() >= area.height() ))
|
||||
{ // Window is too large for the screen, maximize in the
|
||||
// directions necessary
|
||||
if( width() >= area.width() && height() >= area.height() )
|
||||
{
|
||||
maximize( Client::MaximizeFull );
|
||||
geom_restore = QRect(); // use placement when unmaximizing
|
||||
geom_restore = QRect(); // Use placement when unmaximizing
|
||||
}
|
||||
else if ( width() >= area.width() )
|
||||
else if( width() >= area.width() )
|
||||
{
|
||||
maximize( Client::MaximizeHorizontal );
|
||||
geom_restore = QRect(); // use placement when unmaximizing
|
||||
geom_restore.setY( y()); // but only for horizontal direction
|
||||
geom_restore.setHeight( height());
|
||||
geom_restore = QRect(); // Use placement when unmaximizing
|
||||
geom_restore.setY( y() ); // But only for horizontal direction
|
||||
geom_restore.setHeight( height() );
|
||||
}
|
||||
else if ( height() >= area.height() )
|
||||
else if( height() >= area.height() )
|
||||
{
|
||||
maximize( Client::MaximizeVertical );
|
||||
geom_restore = QRect(); // use placement when unmaximizing
|
||||
geom_restore.setX( x()); // but only for vertical direction
|
||||
geom_restore.setWidth( width());
|
||||
geom_restore = QRect(); // Use placement when unmaximizing
|
||||
geom_restore.setX( x() ); // But only for vertical direction
|
||||
geom_restore.setWidth( width() );
|
||||
}
|
||||
}
|
||||
// window may want to be maximized
|
||||
|
||||
// Window may want to be maximized
|
||||
// done after checking that the window isn't larger than the workarea, so that
|
||||
// the restore geometry from the checks above takes precedence, and window
|
||||
// isn't restored larger than the workarea
|
||||
MaximizeMode maxmode = static_cast< MaximizeMode >
|
||||
((( info->state() & NET::MaxVert ) ? MaximizeVertical : 0 )
|
||||
| (( info->state() & NET::MaxHoriz ) ? MaximizeHorizontal : 0 ));
|
||||
MaximizeMode maxmode = static_cast<MaximizeMode>(
|
||||
(( info->state() & NET::MaxVert ) ? MaximizeVertical : 0 ) |
|
||||
(( info->state() & NET::MaxHoriz ) ? MaximizeHorizontal : 0 ));
|
||||
MaximizeMode forced_maxmode = rules()->checkMaximize( maxmode, !isMapped );
|
||||
// either hints were set to maximize, or is forced to maximize,
|
||||
|
||||
// Either hints were set to maximize, or is forced to maximize,
|
||||
// or is forced to non-maximize and hints were set to maximize
|
||||
if( forced_maxmode != MaximizeRestore || maxmode != MaximizeRestore )
|
||||
maximize( forced_maxmode );
|
||||
|
||||
// read other initial states
|
||||
// Read other initial states
|
||||
setShade( rules()->checkShade( info->state() & NET::Shaded ? ShadeNormal : ShadeNone, !isMapped ));
|
||||
setKeepAbove( rules()->checkKeepAbove( info->state() & NET::KeepAbove, !isMapped ));
|
||||
setKeepBelow( rules()->checkKeepBelow( info->state() & NET::KeepBelow, !isMapped ));
|
||||
|
@ -443,133 +434,129 @@ bool Client::manage( Window w, bool isMapped )
|
|||
demandAttention();
|
||||
if( info->state() & NET::Modal )
|
||||
setModal( true );
|
||||
if( fullscreen_mode != FullScreenHack && isFullScreenable())
|
||||
if( fullscreen_mode != FullScreenHack && isFullScreenable() )
|
||||
setFullScreen( rules()->checkFullScreen( info->state() & NET::FullScreen, !isMapped ), false );
|
||||
}
|
||||
|
||||
updateAllowedActions( true );
|
||||
|
||||
// set initial user time directly
|
||||
// Set initial user time directly
|
||||
user_time = readUserTimeMapTimestamp( asn_valid ? &asn_id : NULL, asn_valid ? &asn_data : NULL, session );
|
||||
group()->updateUserTime( user_time ); // and do what Client::updateUserTime() does
|
||||
group()->updateUserTime( user_time ); // And do what Client::updateUserTime() does
|
||||
|
||||
if( isTopMenu()) // they're shown in Workspace::addClient() if their mainwindow
|
||||
hideClient( true ); // is the active one
|
||||
if( isTopMenu()) // They're shown in Workspace::addClient() if their mainwindow
|
||||
hideClient( true ); // Is the active one
|
||||
|
||||
// this should avoid flicker, because real restacking is done
|
||||
// This should avoid flicker, because real restacking is done
|
||||
// only after manage() finishes because of blocking, but the window is shown sooner
|
||||
XLowerWindow( display(), frameId());
|
||||
XLowerWindow( display(), frameId() );
|
||||
if( session && session->stackingOrder != -1 )
|
||||
{
|
||||
sm_stacking_order = session->stackingOrder;
|
||||
workspace()->restoreSessionStackingOrder( this );
|
||||
}
|
||||
|
||||
if( compositing()) // sending ConfigureNotify is done when setting mapping state below,
|
||||
sendSyncRequest(); // getting the first sync response means window is ready for compositing
|
||||
if( compositing() )
|
||||
// Sending ConfigureNotify is done when setting mapping state below,
|
||||
// Getting the first sync response means window is ready for compositing
|
||||
sendSyncRequest();
|
||||
|
||||
if( isShown( true ) && !doNotShow )
|
||||
{
|
||||
if( isDialog())
|
||||
if( isDialog() )
|
||||
Notify::raise( Notify::TransNew );
|
||||
if( isNormalWindow())
|
||||
if( isNormalWindow() )
|
||||
Notify::raise( Notify::New );
|
||||
|
||||
bool allow;
|
||||
if( session )
|
||||
allow = session->active
|
||||
&& ( !workspace()->wasUserInteraction()
|
||||
|| workspace()->activeClient() == NULL || workspace()->activeClient()->isDesktop());
|
||||
allow = session->active &&
|
||||
( !workspace()->wasUserInteraction() || workspace()->activeClient() == NULL ||
|
||||
workspace()->activeClient()->isDesktop() );
|
||||
else
|
||||
allow = workspace()->allowClientActivation( this, userTime(), false );
|
||||
|
||||
// if session saving, force showing new windows (i.e. "save file?" dialogs etc.)
|
||||
// If session saving, force showing new windows (i.e. "save file?" dialogs etc.)
|
||||
// also force if activation is allowed
|
||||
if( !isOnCurrentDesktop() && !isMapped && !session && ( allow || workspace()->sessionSaving()))
|
||||
workspace()->setCurrentDesktop( desktop());
|
||||
if( !isOnCurrentDesktop() && !isMapped && !session && ( allow || workspace()->sessionSaving() ))
|
||||
workspace()->setCurrentDesktop( desktop() );
|
||||
|
||||
bool belongs_to_desktop = false;
|
||||
for( ClientList::ConstIterator it = group()->members().constBegin();
|
||||
it != group()->members().constEnd();
|
||||
++it )
|
||||
if( (*it)->isDesktop())
|
||||
it != group()->members().constEnd();
|
||||
++it )
|
||||
if( (*it)->isDesktop() )
|
||||
{
|
||||
belongs_to_desktop = true;
|
||||
break;
|
||||
}
|
||||
if( !belongs_to_desktop && workspace()->showingDesktop())
|
||||
if( !belongs_to_desktop && workspace()->showingDesktop() )
|
||||
workspace()->resetShowingDesktop( options->showDesktopIsMinimizeAll );
|
||||
|
||||
if( isOnCurrentDesktop() && !isMapped && !allow && (!session || session->stackingOrder < 0 ))
|
||||
if( isOnCurrentDesktop() && !isMapped && !allow && ( !session || session->stackingOrder < 0 ))
|
||||
workspace()->restackClientUnderActive( this );
|
||||
|
||||
updateVisibility();
|
||||
|
||||
if( !isMapped )
|
||||
{
|
||||
if( allow && isOnCurrentDesktop())
|
||||
if( allow && isOnCurrentDesktop() )
|
||||
{
|
||||
if( !isSpecialWindow())
|
||||
if( !isSpecialWindow() )
|
||||
if ( options->focusPolicyIsReasonable() && wantsTabFocus() )
|
||||
workspace()->requestFocus( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !session && !isSpecialWindow())
|
||||
demandAttention();
|
||||
}
|
||||
else if( !session && !isSpecialWindow())
|
||||
demandAttention();
|
||||
}
|
||||
}
|
||||
else if( !doNotShow ) // if( !isShown( true ) && !doNotShow )
|
||||
{
|
||||
updateVisibility();
|
||||
}
|
||||
else // doNotShow
|
||||
{ // SELI HACK !!!
|
||||
hideClient( true );
|
||||
}
|
||||
hideClient( true ); // SELI HACK !!!
|
||||
assert( mapping_state != Withdrawn );
|
||||
blockGeometryUpdates( false );
|
||||
|
||||
if( user_time == CurrentTime || user_time == -1U ) // no known user time, set something old
|
||||
{
|
||||
if( user_time == CurrentTime || user_time == -1U )
|
||||
{ // No known user time, set something old
|
||||
user_time = xTime() - 1000000;
|
||||
if( user_time == CurrentTime || user_time == -1U ) // let's be paranoid
|
||||
if( user_time == CurrentTime || user_time == -1U ) // Let's be paranoid
|
||||
user_time = xTime() - 1000000 + 10;
|
||||
}
|
||||
|
||||
updateWorkareaDiffs();
|
||||
|
||||
// sendSyntheticConfigureNotify(); done when setting mapping state
|
||||
//sendSyntheticConfigureNotify(); // Done when setting mapping state
|
||||
|
||||
delete session;
|
||||
|
||||
ungrabXServer();
|
||||
|
||||
client_rules.discardTemporary();
|
||||
applyWindowRules(); // just in case
|
||||
workspace()->discardUsedWindowRules( this, false ); // remove ApplyNow rules
|
||||
updateWindowRules(); // was blocked while !isManaged()
|
||||
|
||||
// TODO there's a small problem here - isManaged() depends on the mapping state,
|
||||
// but this client is not yet in Workspace's client list at this point, will
|
||||
// be only done in addClient()
|
||||
ungrabXServer();
|
||||
|
||||
client_rules.discardTemporary();
|
||||
applyWindowRules(); // Just in case
|
||||
workspace()->discardUsedWindowRules( this, false ); // Remove ApplyNow rules
|
||||
updateWindowRules(); // Was blocked while !isManaged()
|
||||
|
||||
// TODO: there's a small problem here - isManaged() depends on the mapping state,
|
||||
// but this client is not yet in Workspace's client list at this point, will
|
||||
// be only done in addClient()
|
||||
return true;
|
||||
}
|
||||
|
||||
// called only from manage()
|
||||
void Client::embedClient( Window w, const XWindowAttributes &attr )
|
||||
// Called only from manage()
|
||||
void Client::embedClient( Window w, const XWindowAttributes& attr )
|
||||
{
|
||||
assert( client == None );
|
||||
assert( frameId() == None );
|
||||
assert( wrapper == None );
|
||||
client = w;
|
||||
// we don't want the window to be destroyed when we are destroyed
|
||||
|
||||
// We don't want the window to be destroyed when we are destroyed
|
||||
XAddToSaveSet( display(), client );
|
||||
XSelectInput( display(), client, NoEventMask );
|
||||
XUnmapWindow( display(), client );
|
||||
XWindowChanges wc; // set the border width to 0
|
||||
wc.border_width = 0; // TODO possibly save this, and also use it for initial configuring of the window
|
||||
XWindowChanges wc; // Set the border width to 0
|
||||
wc.border_width = 0; // TODO: Possibly save this, and also use it for initial configuring of the window
|
||||
XConfigureWindow( display(), client, CWBorderWidth, &wc );
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
|
@ -578,36 +565,35 @@ void Client::embedClient( Window w, const XWindowAttributes &attr )
|
|||
swa.border_pixel = 0;
|
||||
|
||||
Window frame = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
|
||||
attr.depth, InputOutput, attr.visual,
|
||||
CWColormap | CWBackPixmap | CWBorderPixel, &swa );
|
||||
attr.depth, InputOutput, attr.visual, CWColormap | CWBackPixmap | CWBorderPixel, &swa );
|
||||
setWindowHandles( client, frame );
|
||||
wrapper = XCreateWindow( display(), frame, 0, 0, 1, 1, 0,
|
||||
attr.depth, InputOutput, attr.visual,
|
||||
CWColormap | CWBackPixmap | CWBorderPixel, &swa );
|
||||
attr.depth, InputOutput, attr.visual, CWColormap | CWBackPixmap | CWBorderPixel, &swa );
|
||||
|
||||
XDefineCursor( display(), frame, QCursor( Qt::ArrowCursor ).handle());
|
||||
// some apps are stupid and don't define their own cursor - set the arrow one for them
|
||||
XDefineCursor( display(), wrapper, QCursor( Qt::ArrowCursor ).handle());
|
||||
XDefineCursor( display(), frame, QCursor( Qt::ArrowCursor ).handle() );
|
||||
// Some apps are stupid and don't define their own cursor - set the arrow one for them
|
||||
XDefineCursor( display(), wrapper, QCursor( Qt::ArrowCursor ).handle() );
|
||||
XReparentWindow( display(), client, wrapper, 0, 0 );
|
||||
XSelectInput( display(), frame,
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
KeymapStateMask |
|
||||
ButtonMotionMask |
|
||||
PointerMotionMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
PropertyChangeMask |
|
||||
StructureNotifyMask | SubstructureRedirectMask );
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
KeymapStateMask |
|
||||
ButtonMotionMask |
|
||||
PointerMotionMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
FocusChangeMask |
|
||||
ExposureMask |
|
||||
PropertyChangeMask |
|
||||
StructureNotifyMask | SubstructureRedirectMask );
|
||||
XSelectInput( display(), wrapper, ClientWinMask | SubstructureNotifyMask );
|
||||
XSelectInput( display(), client,
|
||||
FocusChangeMask |
|
||||
PropertyChangeMask |
|
||||
ColormapChangeMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
KeyPressMask | KeyReleaseMask
|
||||
);
|
||||
FocusChangeMask |
|
||||
PropertyChangeMask |
|
||||
ColormapChangeMask |
|
||||
EnterWindowMask | LeaveWindowMask |
|
||||
KeyPressMask | KeyReleaseMask
|
||||
);
|
||||
|
||||
updateMouseGrab();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue