From ec0fa1789a81610d66b6aac2b138e759a92da698 Mon Sep 17 00:00:00 2001 From: Rivo Laks Date: Thu, 27 Sep 2007 14:53:52 +0000 Subject: [PATCH] Automatically restart KWin when it crashes. If it crashes at least two times in a row then disable compositing. svn path=/trunk/KDE/kdebase/workspace/; revision=717778 --- main.cpp | 33 +++++++++++++++++++++++++++++++++ main.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/main.cpp b/main.cpp index 608743fdd4..df6459a2c4 100644 --- a/main.cpp +++ b/main.cpp @@ -19,6 +19,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include #include +#include #include #include #include @@ -84,6 +85,8 @@ int x11ErrorHandler(Display *d, XErrorEvent *e) return 0; } +int Application::crashes = 0; + Application::Application( ) : KApplication( ), owner( screen_number ) { @@ -106,6 +109,18 @@ Application::Application( ) } connect( &owner, SIGNAL( lostOwnership()), SLOT( lostSelection())); + KCrash::setEmergencySaveFunction( Application::crashHandler ); + crashes = args->getOption("crashes").toInt(); + // Disable compositing if we have had too many crashes + if( crashes >= 2 ) + { + kDebug() << "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 config->reparseConfiguration(); @@ -178,6 +193,23 @@ static void sighandler(int) QApplication::exit(); } +void Application::crashHandler(int signal) + { + crashes++; + + fprintf( stderr, "Application::crashHandler() called with signal %d; recent crashes: %d\n", signal, crashes ); + char cmd[1024]; + sprintf( cmd, "kwin --crashes %d &", crashes ); + + sleep( 1 ); + system( cmd ); + } + +void Application::resetCrashesCount() + { + crashes = 0; + } + } // namespace @@ -267,6 +299,7 @@ KDE_EXPORT int kdemain( int argc, char * argv[] ) KCmdLineOptions args; args.add("lock", ki18n("Disable configuration options")); args.add("replace", ki18n("Replace already-running ICCCM2.0-compliant window manager")); + args.add("crashes ", ki18n("Indicate that KWin has recently crashed n times")); KCmdLineArgs::addCmdLineOptions( args ); if (signal(SIGTERM, KWin::sighandler) == SIG_IGN) diff --git a/main.h b/main.h index 043ef1778b..183403b42a 100644 --- a/main.h +++ b/main.h @@ -29,11 +29,14 @@ class Application : public KApplication protected: bool x11EventFilter( XEvent * ); bool notify( QObject* o, QEvent* e ); + static void crashHandler(int signal); private slots: void lostSelection(); + void resetCrashesCount(); private: KWinSelectionOwner owner; + static int crashes; }; } // namespace