mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
kwin: replace custom crash handler with the auto-restart feature of KCrash
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
5e6ea65ed8
commit
36ec6aac95
5 changed files with 1 additions and 122 deletions
|
@ -815,23 +815,6 @@ void Workspace::setClientIsMoving(Client *c)
|
|||
--block_focus;
|
||||
}
|
||||
|
||||
// When kwin crashes, windows will not be gravitated back to their original position
|
||||
// and will remain offset by the size of the decoration. So when restarting, fix this
|
||||
// (the property with the size of the frame remains on the window after the crash).
|
||||
void Workspace::fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_reply_t *geometry)
|
||||
{
|
||||
NETWinInfo i(display(), w, rootWindow(), NET::WMFrameExtents);
|
||||
NETStrut frame = i.frameExtents();
|
||||
|
||||
if (frame.left != 0 || frame.top != 0) {
|
||||
// left and top needed due to narrowing conversations restrictions in C++11
|
||||
const uint32_t left = frame.left;
|
||||
const uint32_t top = frame.top;
|
||||
const uint32_t values[] = { geometry->x - left, geometry->y - top };
|
||||
xcb_configure_window(connection(), w, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values);
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
// Client
|
||||
//********************************************
|
||||
|
|
|
@ -201,51 +201,6 @@ static int x11ErrorHandler(Display* d, XErrorEvent* e)
|
|||
return 0;
|
||||
}
|
||||
|
||||
class AlternativeWMDialog : public KDialog
|
||||
{
|
||||
public:
|
||||
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:");
|
||||
QLabel* textLabel = new QLabel(text, mainWidget);
|
||||
layout->addWidget(textLabel);
|
||||
wmList = new KComboBox(mainWidget);
|
||||
wmList->setEditable(true);
|
||||
layout->addWidget(wmList);
|
||||
|
||||
addWM("metacity");
|
||||
addWM("openbox");
|
||||
addWM("fvwm2");
|
||||
addWM("kwin");
|
||||
|
||||
setMainWidget(mainWidget);
|
||||
|
||||
raise();
|
||||
centerOnScreen(this);
|
||||
}
|
||||
|
||||
void addWM(const QString& wm) {
|
||||
// TODO: Check if WM is installed
|
||||
if (!KStandardDirs::findExe(wm).isEmpty())
|
||||
wmList->addItem(wm);
|
||||
}
|
||||
QString selectedWM() const {
|
||||
return wmList->currentText();
|
||||
}
|
||||
|
||||
private:
|
||||
KComboBox* wmList;
|
||||
};
|
||||
|
||||
int Application::crashes = 0;
|
||||
|
||||
Application::Application()
|
||||
: KApplication()
|
||||
, owner(new KSelectionOwner(make_selection_atom(screen_number), screen_number, this))
|
||||
|
@ -294,35 +249,7 @@ bool Application::setup()
|
|||
connect(owner, SIGNAL(lostOwnership()), this, SLOT(lostSelection()), Qt::DirectConnection);
|
||||
|
||||
KApplication::quitOnSignal();
|
||||
KCrash::setCrashHandler(Application::crashHandler);
|
||||
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 {
|
||||
return false;
|
||||
}
|
||||
if (cmd.length() > 500) {
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
if (crashes >= 2) {
|
||||
// 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()));
|
||||
KCrash::setFlags(KCrash::AutoRestart);
|
||||
|
||||
initting = true; // Startup...
|
||||
// first load options - done internally by a different thread
|
||||
|
@ -371,27 +298,6 @@ bool Application::notify(QObject* o, QEvent* e)
|
|||
return KApplication::notify(o, e);
|
||||
}
|
||||
|
||||
void Application::crashHandler(int signal)
|
||||
{
|
||||
KDE_signal(signal, SIG_DFL);
|
||||
|
||||
crashes++;
|
||||
|
||||
::fprintf(stderr, "Application::crashHandler() called with signal %d; recent crashes: %d\n", signal, crashes);
|
||||
char cmd[1024];
|
||||
::sprintf(cmd, "%s --crashes %d &",
|
||||
QFile::encodeName(QCoreApplication::applicationFilePath()).constData(), crashes);
|
||||
|
||||
::sleep(1);
|
||||
::system(cmd);
|
||||
::exit(signal);
|
||||
}
|
||||
|
||||
void Application::resetCrashesCount()
|
||||
{
|
||||
crashes = 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
static const char version[] = KWIN_VERSION_STRING;
|
||||
|
@ -471,7 +377,6 @@ int main(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 <n>", ki18n("Indicate that KWin has recently crashed n times"));
|
||||
KCmdLineArgs::addCmdLineOptions(args);
|
||||
|
||||
KWin::Application a;
|
||||
|
|
|
@ -41,15 +41,12 @@ public:
|
|||
protected:
|
||||
bool x11EventFilter(XEvent*);
|
||||
bool notify(QObject* o, QEvent* e);
|
||||
static void crashHandler(int signal);
|
||||
|
||||
private slots:
|
||||
void lostSelection();
|
||||
void resetCrashesCount();
|
||||
|
||||
private:
|
||||
KSelectionOwner* owner;
|
||||
static int crashes;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -293,8 +293,6 @@ void Workspace::init()
|
|||
// Begin updates blocker block
|
||||
StackingUpdatesBlocker blocker(this);
|
||||
|
||||
bool fixoffset = KCmdLineArgs::parsedArgs()->getOption("crashes").toInt() > 0;
|
||||
|
||||
Xcb::Tree tree(rootWindow());
|
||||
xcb_window_t *wins = xcb_query_tree_children(tree.data());
|
||||
|
||||
|
@ -321,9 +319,6 @@ void Workspace::init()
|
|||
// ### This will request the attributes again
|
||||
createUnmanaged(wins[i]);
|
||||
} else if (attr->map_state != XCB_MAP_STATE_UNMAPPED) {
|
||||
if (fixoffset) {
|
||||
fixPositionAfterCrash(wins[i], windowGeometries[i].data());
|
||||
}
|
||||
|
||||
// ### This will request the attributes again
|
||||
createClient(wins[i], true);
|
||||
|
|
|
@ -433,7 +433,6 @@ private:
|
|||
bool keepTransientAbove(const Client* mainwindow, const Client* transient);
|
||||
void blockStackingUpdates(bool block);
|
||||
void updateToolWindows(bool also_hide);
|
||||
void fixPositionAfterCrash(xcb_window_t w, const xcb_get_geometry_reply_t *geom);
|
||||
void saveOldScreenSizes();
|
||||
|
||||
/// This is the right way to create a new client
|
||||
|
|
Loading…
Add table
Reference in a new issue