diff --git a/kwin/kcmkwin/kwinoptions/windows.cpp b/kwin/kcmkwin/kwinoptions/windows.cpp index 9e81bc053..f3de197d5 100644 --- a/kwin/kcmkwin/kwinoptions/windows.cpp +++ b/kwin/kcmkwin/kwinoptions/windows.cpp @@ -1491,6 +1491,7 @@ KTranslucencyConfig::KTranslucencyConfig (bool _standAlone, KConfig *_config, TQ connect(shadowTopOffset, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(resetKompmgr())); connect(shadowLeftOffset, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(resetKompmgr())); connect(shadowColor, TQT_SIGNAL(changed(const TQColor&)), TQT_SLOT(resetKompmgr())); + connect(fadeInWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(fadeInMenuWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(fadeOnOpacityChange, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr())); connect(fadeInSpeed, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(resetKompmgr())); @@ -1695,8 +1696,7 @@ void KTranslucencyConfig::startKompmgr() bool ret; KProcess proc; proc << "kompmgr"; - ret = proc.start(KProcess::DontCare, KProcess::AllOutput); - proc.detach(); + ret = proc.start(KProcess::DontCare); } void KTranslucencyConfig::showWarning(bool alphaActivated) diff --git a/kwin/kompmgr/kompmgr.c b/kwin/kompmgr/kompmgr.c index ceea0ac30..910622d73 100644 --- a/kwin/kompmgr/kompmgr.c +++ b/kwin/kompmgr/kompmgr.c @@ -34,8 +34,10 @@ * CHANGELOG: * http://patchwork.freedesktop.org/patch/1049/ [Add default background color option] 08/11/2011 * http://patchwork.freedesktop.org/patch/1052/ [Prevent flicker on root pixmap change] 08/11/2011 - * Added SIGUSER1 handler to change process UID [Prevent flicker on login] 08/12/2011 + * Added SIGUSR1 handler to change process UID [Prevent flicker on login] 08/12/2011 * Added ability to write PID of process to home directory 08/14/2011 + * Added SIGUSR2 handler to reload settings [Prevent flicker on settings change] 08/14/2011 + * Added SIGTERM handler to clean up stale PID files on exit 08/14/2011 * * TODO: * http://patchwork.freedesktop.org/patch/1053/ [Fix window mapping with re-used window ids] @@ -76,7 +78,7 @@ check baghira.sf.net for more infos #define _LEFTWIDTH_(x) (x & 0xff) /* #define USE_ENV_HOME 1 */ -/* #define WRITE_PID_FILE 1 */ +#define WRITE_PID_FILE 1 #ifndef USE_ENV_HOME #include @@ -297,7 +299,7 @@ void write_pid_file(pid_t pid) home = getenv("HOME"); #endif const char *filename; - const char *configfile = "/.kompmgr.pid"; + const char *configfile = "/.kompmgr.pid"; int n = strlen(home)+strlen(configfile)+1; filename = (char*)malloc(n*sizeof(char)); memset(filename,0,n); @@ -311,8 +313,10 @@ void write_pid_file(pid_t pid) char buffer[255]; sprintf(buffer, "%d", pid); pFile = fopen(filename, "w"); - fwrite(buffer,1,strlen(buffer), pFile); - fclose(pFile); + if (pFile) { + fwrite(buffer,1,strlen(buffer), pFile); + fclose(pFile); + } free(filename); filename = NULL; @@ -353,46 +357,59 @@ void delete_pid_file() void handle_siguser (int sig) { - char newuid[1024]; + int uidnum; + if (sig == SIGTERM) { + delete_pid_file(); + exit(0); + return; + } + if (sig == SIGUSR1) { + char newuid[1024]; #ifndef NDEBUG - printf("Enter the new user ID:\n\r"); fflush(stdout); + printf("Enter the new user ID:\n\r"); fflush(stdout); #endif - char *eof; - newuid[0] = '\0'; - newuid[sizeof(newuid)-1] = '\0'; - eof = fgets(newuid, sizeof(newuid), stdin); - int uidnum = atoi(newuid); + char *eof; + newuid[0] = '\0'; + newuid[sizeof(newuid)-1] = '\0'; + eof = fgets(newuid, sizeof(newuid), stdin); + uidnum = atoi(newuid); #ifndef NDEBUG - printf("Setting kompmgr process uid to %d...\n\r", uidnum); fflush(stdout); + printf("Setting kompmgr process uid to %d...\n\r", uidnum); fflush(stdout); #endif - delete_pid_file(); - setuid(uidnum); - write_pid_file(getpid()); + delete_pid_file(); + setuid(uidnum); + write_pid_file(getpid()); + } + else { + uidnum = getuid(); + } + if ((sig == SIGUSR1) || (sig == SIGUSR2)) { #ifdef USE_ENV_HOME - const char *home = getenv("HOME"); + const char *home = getenv("HOME"); #else - const char *home; - struct passwd *p; - p = getpwuid(uidnum); - if (p) - home = p->pw_dir; - else - home = getenv("HOME"); + const char *home; + struct passwd *p; + p = getpwuid(uidnum); + if (p) + home = p->pw_dir; + else + home = getenv("HOME"); #endif - const char *filename; - const char *configfile = "/.xcompmgrrc"; - int n = strlen(home)+strlen(configfile)+1; - filename = (char*)malloc(n*sizeof(char)); - memset(filename,0,n); - strcat(filename, home); - strcat(filename, configfile); - - loadConfig(filename); /* reload the configuration file */ - - free(filename); - filename = NULL; + const char *filename; + const char *configfile = "/.xcompmgrrc"; + int n = strlen(home)+strlen(configfile)+1; + filename = (char*)malloc(n*sizeof(char)); + memset(filename,0,n); + strcat(filename, home); + strcat(filename, configfile); + + loadConfig(filename); /* reload the configuration file */ + + free(filename); + filename = NULL; + } } fade * @@ -2712,9 +2729,8 @@ main (int argc, char **argv) usr_action.sa_mask = block_mask; usr_action.sa_flags = 0; sigaction(SIGUSR1, &usr_action, NULL); - - // atexit(delete_pid_file); // [FIXME] For some reason this gets confused and deletes the file early - write_pid_file(getpid()); + sigaction(SIGUSR2, &usr_action, NULL); + sigaction(SIGTERM, &usr_action, NULL); loadConfig(NULL); /*we do that before cmdline-parsing, so config-values can be overridden*/ /*used for shadow colors*/ @@ -2931,6 +2947,11 @@ main (int argc, char **argv) ufd.events = POLLIN; if (!autoRedirect) paint_all (dpy, None); + + /* Under no circumstances should these two lines EVER be moved earlier in main() than this point */ + atexit(delete_pid_file); + write_pid_file(getpid()); + for (;;) { /* dump_wins (); */ diff --git a/kwin/workspace.cpp b/kwin/workspace.cpp index 4d3199a18..77e22af6f 100644 --- a/kwin/workspace.cpp +++ b/kwin/workspace.cpp @@ -45,6 +45,8 @@ License. See the file "COPYING" for the exact licensing terms. #include #include +#include + namespace KWinInternal { @@ -221,6 +223,57 @@ Workspace::Workspace( bool restore ) *kompmgr << "kompmgr"; startKompmgr(); } + else + { + // If kompmgr is already running, send it SIGTERM + // Attempt to load the kompmgr pid file + const char *home; + struct passwd *p; + p = getpwuid(getuid()); + if (p) + home = p->pw_dir; + else + home = getenv("HOME"); + char *filename; + const char *configfile = "/.kompmgr.pid"; + int n = strlen(home)+strlen(configfile)+1; + filename = (char*)malloc(n*sizeof(char)); + memset(filename,0,n); + strcat(filename, home); + strcat(filename, configfile); + + printf("reading '%s' as kompmgr pidfile\n\n", filename); + + // Now that we did all that by way of introduction...read the file! + FILE *pFile; + char buffer[255]; + pFile = fopen(filename, "r"); + int kompmgrpid = 0; + if (pFile) + { + // obtain file size + fseek (pFile , 0 , SEEK_END); + unsigned long lSize = ftell (pFile); + if (lSize > 254) + lSize = 254; + rewind (pFile); + size_t result = fread (buffer, 1, lSize, pFile); + fclose(pFile); + kompmgrpid = atoi(buffer); + } + + free(filename); + filename = NULL; + + if (kompmgrpid) + { + kill(kompmgrpid, SIGTERM); + } + else + { + stopKompmgr(); + } + } } @@ -1023,9 +1076,70 @@ void Workspace::slotReconfigure() if (options->resetKompmgr) // need restart { bool tmp = options->useTranslucency; - stopKompmgr(); + + // If kompmgr is already running, sending SIGUSR2 will force a reload of its settings + // Attempt to load the kompmgr pid file + const char *home; + struct passwd *p; + p = getpwuid(getuid()); + if (p) + home = p->pw_dir; + else + home = getenv("HOME"); + char *filename; + const char *configfile = "/.kompmgr.pid"; + int n = strlen(home)+strlen(configfile)+1; + filename = (char*)malloc(n*sizeof(char)); + memset(filename,0,n); + strcat(filename, home); + strcat(filename, configfile); + + printf("reading '%s' as kompmgr pidfile\n\n", filename); + + // Now that we did all that by way of introduction...read the file! + FILE *pFile; + char buffer[255]; + pFile = fopen(filename, "r"); + int kompmgrpid = 0; + if (pFile) + { + // obtain file size + fseek (pFile , 0 , SEEK_END); + unsigned long lSize = ftell (pFile); + if (lSize > 254) + lSize = 254; + rewind (pFile); + size_t result = fread (buffer, 1, lSize, pFile); + fclose(pFile); + kompmgrpid = atoi(buffer); + } + + free(filename); + filename = NULL; + if (tmp) - TQTimer::singleShot( 200, this, TQT_SLOT(startKompmgr()) ); // wait some time to ensure system's ready for restart + { + if (kompmgrpid) + { + kill(kompmgrpid, SIGUSR2); + } + else + { + stopKompmgr(); + TQTimer::singleShot( 200, this, TQT_SLOT(startKompmgr()) ); // wait some time to ensure system's ready for restart + } + } + else + { + if (kompmgrpid) + { + kill(kompmgrpid, SIGTERM); + } + else + { + stopKompmgr(); + } + } } } @@ -2620,8 +2734,9 @@ void Workspace::startKompmgr() void Workspace::stopKompmgr() { - if (!kompmgr || !kompmgr->isRunning()) + if (!kompmgr || !kompmgr->isRunning()) { return; + } delete kompmgr_selection; kompmgr_selection = NULL; kompmgr->disconnect(this, TQT_SLOT(restartKompmgr())); @@ -2647,21 +2762,28 @@ void Workspace::unblockKompmgrRestart() void Workspace::restartKompmgr( KProcess *proc ) // this is for inernal purpose (crashhandling) only, usually you want to use workspace->stopKompmgr(); TQTimer::singleShot(200, workspace, TQT_SLOT(startKompmgr())); { + bool crashed; if (proc->signalled()) { // looks like kompmgr may have crashed int exit_signal_number = proc->exitSignal(); if ( (exit_signal_number == SIGILL) || (exit_signal_number == SIGTRAP) || (exit_signal_number == SIGABRT) || (exit_signal_number == SIGSYS) || (exit_signal_number == SIGFPE) || (exit_signal_number == SIGBUS) || (exit_signal_number == SIGSEGV) ) { - if (!allowKompmgrRestart) // uh oh, it crashed recently already - { - delete kompmgr_selection; - kompmgr_selection = NULL; - options->useTranslucency = FALSE; + crashed = true; + } + else { + crashed = false; + } + if (!allowKompmgrRestart) // uh oh, it exited recently already + { + delete kompmgr_selection; + kompmgr_selection = NULL; + options->useTranslucency = FALSE; + if (crashed) { KProcess proc; proc << "kdialog" << "--error" << i18n( "The Composite Manager crashed twice within a minute and is therefore disabled for this session.") << "--title" << i18n("Composite Manager Failure"); proc.start(KProcess::DontCare); - return; - } + } + return; } if (!kompmgr) return;