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:
Ivailo Monev 2022-12-07 02:58:39 +02:00
parent 5e6ea65ed8
commit 36ec6aac95
5 changed files with 1 additions and 122 deletions

View file

@ -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
//********************************************

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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