13#include <config-kwin.h> 
   28#include <KConfigGroup> 
   30#include <KGlobalAccel> 
   31#include <KLocalizedString> 
   32#include <KSelectionOwner> 
   33#include <KSignalHandler> 
   37#include <QCommandLineParser> 
   39#include <QDialogButtonBox> 
   43#include <QSurfaceFormat> 
   45#include <qplatformdefs.h> 
   46#include <private/qtx11extras_p.h> 
   53Q_LOGGING_CATEGORY(KWIN_CORE, 
"kwin_core", QtWarningMsg)
 
   64        QWidget *mainWidget = 
new QWidget(
this);
 
   65        QVBoxLayout *layout = 
new QVBoxLayout(mainWidget);
 
   66        QString text = i18n(
"KWin is unstable.\n" 
   67                            "It seems to have crashed several times in a row.\n" 
   68                            "You can select another window manager to run:");
 
   69        QLabel *textLabel = 
new QLabel(text, mainWidget);
 
   70        layout->addWidget(textLabel);
 
   71        wmList = 
new QComboBox(mainWidget);
 
   72        wmList->setEditable(
true);
 
   73        layout->addWidget(wmList);
 
   75        addWM(QStringLiteral(
"metacity"));
 
   76        addWM(QStringLiteral(
"openbox"));
 
   77        addWM(QStringLiteral(
"fvwm2"));
 
   78        addWM(QStringLiteral(
"kwin_x11"));
 
   80        QVBoxLayout *mainLayout = 
new QVBoxLayout(
this);
 
   81        mainLayout->addWidget(mainWidget);
 
   82        QDialogButtonBox *buttons = 
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, 
this);
 
   83        buttons->button(QDialogButtonBox::Ok)->setDefault(
true);
 
   84        connect(buttons, &QDialogButtonBox::accepted, 
this, &QDialog::accept);
 
   85        connect(buttons, &QDialogButtonBox::rejected, 
this, &QDialog::reject);
 
   86        mainLayout->addWidget(buttons);
 
 
   94        if (!QStandardPaths::findExecutable(wm).isEmpty()) {
 
 
  100        return wmList->currentText();
 
 
 
  112        : KSelectionOwner(make_selection_atom())
 
 
  117    bool genericReply(xcb_atom_t target_P, xcb_atom_t property_P, xcb_window_t requestor_P)
 override 
  119        if (target_P == xa_version) {
 
  121            xcb_change_property(kwinApp()->x11Connection(), XCB_PROP_MODE_REPLACE, requestor_P,
 
  122                                property_P, XCB_ATOM_INTEGER, 32, 2, 
version);
 
  124            return KSelectionOwner::genericReply(target_P, property_P, requestor_P);
 
  129    void replyTargets(xcb_atom_t property_P, xcb_window_t requestor_P)
 override 
  131        KSelectionOwner::replyTargets(property_P, requestor_P);
 
  132        xcb_atom_t 
atoms[1] = {xa_version};
 
  134        xcb_change_property(kwinApp()->x11Connection(), XCB_PROP_MODE_APPEND, requestor_P,
 
  135                            property_P, XCB_ATOM_ATOM, 32, 1, 
atoms);
 
  138    void getAtoms()
 override 
  140        KSelectionOwner::getAtoms();
 
  141        if (xa_version == XCB_ATOM_NONE) {
 
  142            constexpr QByteArrayView name{
"VERSION"};
 
  143            UniqueCPtr<xcb_intern_atom_reply_t> atom(xcb_intern_atom_reply(
 
  144                kwinApp()->x11Connection(),
 
  145                xcb_intern_atom_unchecked(kwinApp()->x11Connection(), 
false, name.length(), name.constData()),
 
  148                xa_version = atom->atom;
 
  153    xcb_atom_t make_selection_atom()
 
  155        constexpr QByteArrayView screen{
"WM_S0"};
 
  156        UniqueCPtr<xcb_intern_atom_reply_t> atom(xcb_intern_atom_reply(
 
  157            kwinApp()->x11Connection(),
 
  158            xcb_intern_atom_unchecked(kwinApp()->x11Connection(), 
false, screen.length(), screen.constData()),
 
  161            return XCB_ATOM_NONE;
 
  165    static xcb_atom_t xa_version;
 
 
  167xcb_atom_t KWinSelectionOwner::xa_version = XCB_ATOM_NONE;
 
  194    if (owner != 
nullptr && owner->ownerWindow() != XCB_WINDOW_NONE) {
 
  195        Xcb::setInputFocus(XCB_INPUT_FOCUS_POINTER_ROOT);
 
 
  218        return outlineVisual;
 
 
  243void ApplicationX11::lostSelection()
 
  255    Xcb::selectInput(kwinApp()->
x11RootWindow(), XCB_EVENT_MASK_PROPERTY_CHANGE);
 
  264    owner = std::make_unique<KWinSelectionOwner>();
 
  265    connect(owner.get(), &KSelectionOwner::failedToClaimOwnership, [] {
 
  266        fputs(i18n(
"kwin: unable to claim manager selection, another wm running? (try using --replace)\n").toLocal8Bit().constData(), stderr);
 
  269    connect(owner.get(), &KSelectionOwner::lostOwnership, 
this, &ApplicationX11::lostSelection);
 
  270    connect(owner.get(), &KSelectionOwner::claimedOwnership, 
this, [
this] {
 
  271        installNativeX11EventFilter();
 
  274        if (!outputBackend()->initialize()) {
 
  279        const uint32_t maskValues[] = {XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT};
 
  281                                                                        xcb_change_window_attributes_checked(kwinApp()->
x11Connection(),
 
  286            fputs(i18n(
"kwin: another window manager is running (try using --replace)\n").toLocal8Bit().constData(), stderr);
 
  294        connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutActiveChanged, 
this, [
this](QAction *triggeredAction) {
 
  295            QVariant timestamp = triggeredAction->property(
"org.kde.kglobalaccel.activationTimestamp");
 
  297            const quint32 t = timestamp.toULongLong(&ok);
 
  316    owner->claim(m_replace || wasCrash(), 
true);
 
  320    createTabletModeManager();
 
 
  323void ApplicationX11::setupCrashHandler()
 
  325    KCrash::setEmergencySaveFunction(ApplicationX11::crashHandler);
 
  328void ApplicationX11::crashChecking()
 
  333        AlternativeWMDialog dialog;
 
  334        QString cmd = QStringLiteral(
"kwin_x11");
 
  335        if (dialog.exec() == QDialog::Accepted) {
 
  336            cmd = dialog.selectedWM();
 
  340        if (cmd.length() > 500) {
 
  341            qCDebug(KWIN_CORE) << 
"Command is too long, truncating";
 
  344        qCDebug(KWIN_CORE) << 
"Starting" << cmd << 
"and exiting";
 
  346        sprintf(buf, 
"%s &", cmd.toLatin1().data());
 
  351    QTimer::singleShot(15 * 1000, 
this, &Application::resetCrashesCount);
 
  354void ApplicationX11::notifyKSplash()
 
  357    QDBusMessage ksplashProgressMessage = QDBusMessage::createMethodCall(QStringLiteral(
"org.kde.KSplash"),
 
  358                                                                         QStringLiteral(
"/KSplash"),
 
  359                                                                         QStringLiteral(
"org.kde.KSplash"),
 
  360                                                                         QStringLiteral(
"setStage"));
 
  361    ksplashProgressMessage.setArguments(QList<QVariant>() << QStringLiteral(
"wm"));
 
  362    QDBusConnection::sessionBus().asyncCall(ksplashProgressMessage);
 
  365void ApplicationX11::crashHandler(
int signal)
 
  369    fprintf(stderr, 
"Application::crashHandler() called with signal %d; recent crashes: %d\n", signal, crashes);
 
  371    sprintf(cmd, 
"%s --crashes %d &",
 
  372            QFile::encodeName(QCoreApplication::applicationFilePath()).constData(), crashes);
 
  380int main(
int argc, 
char *argv[])
 
  385    signal(SIGPIPE, SIG_IGN);
 
  388    setenv(
"QT_QPA_PLATFORM", 
"xcb", 
true);
 
  391    setenv(
"QT_ENABLE_HIGHDPI_SCALING", 
"0", 
true);
 
  393    qunsetenv(
"QT_SCALE_FACTOR");
 
  394    qunsetenv(
"QT_SCREEN_SCALE_FACTORS");
 
  397    QCoreApplication::setAttribute(Qt::AA_DisableSessionManager);
 
  399    QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
 
  401    QSurfaceFormat format = QSurfaceFormat::defaultFormat();
 
  403    format.setOptions(QSurfaceFormat::ResetNotification);
 
  405    format.setSwapInterval(0);
 
  406    QSurfaceFormat::setDefaultFormat(format);
 
  411    qunsetenv(
"QT_QPA_PLATFORM");
 
  412    qunsetenv(
"QT_ENABLE_HIGHDPI_SCALING");
 
  416    KSignalHandler::self()->watchSignal(SIGTERM);
 
  417    KSignalHandler::self()->watchSignal(SIGINT);
 
  418    KSignalHandler::self()->watchSignal(SIGHUP);
 
  419    QObject::connect(KSignalHandler::self(), &KSignalHandler::signalReceived,
 
  420                     &a, &QCoreApplication::exit);
 
  424    QCommandLineOption replaceOption(QStringLiteral(
"replace"), i18n(
"Replace already-running ICCCM2.0-compliant window manager"));
 
  426    QCommandLineParser parser;
 
  428    parser.addOption(replaceOption);
 
  429#if KWIN_BUILD_ACTIVITIES 
  430    QCommandLineOption noActivitiesOption(QStringLiteral(
"no-kactivities"),
 
  431                                          i18n(
"Disable KActivities integration."));
 
  432    parser.addOption(noActivitiesOption);
 
  438#if KWIN_BUILD_ACTIVITIES 
  439    if (parser.isSet(noActivitiesOption)) {
 
  440        a.setUseKActivities(
false);
 
  445    if (a.platformName().toLower() != QStringLiteral(
"xcb")) {
 
  446        fprintf(stderr, 
"%s: FATAL ERROR expecting platform xcb but got platform %s\n",
 
  447                argv[0], qPrintable(a.platformName()));
 
  450    if (!QX11Info::display()) {
 
  451        fprintf(stderr, 
"%s: FATAL ERROR KWin requires Xlib support in the xcb plugin. Do not configure Qt with -no-xcb-xlib\n",
 
 
  463#include "main_x11.moc" 
  465#include "moc_main_x11.cpp" 
void addWM(const QString &wm)
QString selectedWM() const
OutputBackend * outputBackend() const
void destroyColorManager()
static void createAboutData()
virtual std::unique_ptr< OutlineVisual > createOutline(Outline *outline)
void setX11RootWindow(xcb_window_t root)
static void setupMalloc()
void setSession(std::unique_ptr< Session > &&session)
void setOutputBackend(std::unique_ptr< OutputBackend > &&backend)
void setX11Time(xcb_timestamp_t timestamp, TimestampUpdate force=TimestampUpdate::OnlyIfLarger)
void processCommandLine(QCommandLineParser *parser)
void setProcessStartupEnvironment(const QProcessEnvironment &environment)
void removeNativeX11EventFilter()
void createColorManager()
static void setupLocalizedString()
void setupCommandLine(QCommandLineParser *parser)
void setX11Connection(xcb_connection_t *c)
ApplicationX11(int &argc, char **argv)
void setReplace(bool replace)
void startInteractiveWindowSelection(std::function< void(KWin::Window *)> callback, const QByteArray &cursorName=QByteArray()) override
std::unique_ptr< OutlineVisual > createOutline(Outline *outline) override
void performStartup() override
void startInteractivePositionSelection(std::function< void(const QPointF &)> callback) override
std::unique_ptr< Edge > createScreenEdge(ScreenEdges *parent) override
std::unique_ptr< Cursor > createPlatformCursor() override
PlatformCursorImage cursorImage() const override
~ApplicationX11() override
void createEffectsHandler(Compositor *compositor, WorkspaceScene *scene) override
This class is used to show the outline of a given geometry.
Class for controlling screen edges.
static std::unique_ptr< Session > create()
static X11Compositor * create(QObject *parent=nullptr)
KWIN_EXPORT Atoms * atoms
std::unique_ptr< T, CDeleter > UniqueCPtr