Git commit 5cbd28f9a0d4a5e94eab0434493e47cd7b650fe1 by Martin Fl=C3=B6ser. Committed on 30/09/2017 at 11:03. Pushed by graesslin into branch 'master'. Move X11 specific Workspace initialization code into dedicated method Summary: This is required to start KWin/Wayland without XWayland support or delayed XWayland support. Test Plan: Run kwin_x11 in a nested Xephyr Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7897 M +0 -3 main.cpp M +139 -115 workspace.cpp M +1 -0 workspace.h https://commits.kde.org/kwin/5cbd28f9a0d4a5e94eab0434493e47cd7b650fe1 diff --git a/main.cpp b/main.cpp index 7e15528e7..765c2af51 100644 --- a/main.cpp +++ b/main.cpp @@ -268,9 +268,6 @@ void Application::notifyKSplash() = void Application::createWorkspace() { - // ensure the helper atoms are retrieved before we create the Workspace - atoms->retrieveHelpers(); - // we want all QQuickWindows with an alpha buffer, do here as Workspac= e might create QQuickWindows QQuickWindow::setDefaultAlphaBuffer(true); = diff --git a/workspace.cpp b/workspace.cpp index 8610f79e4..2dc16a31f 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -133,9 +133,6 @@ Workspace::Workspace(const QString &sessionKey) = _self =3D this; = - // first initialize the extensions - Xcb::Extensions::self(); - #ifdef KWIN_BUILD_ACTIVITIES Activities *activities =3D nullptr; if (kwinApp()->usesKActivities()) { @@ -151,8 +148,6 @@ Workspace::Workspace(const QString &sessionKey) = options->loadConfig(); options->loadCompositingConfig(false); - ColorMapper *colormaps =3D new ColorMapper(this); - connect(this, &Workspace::clientActivated, colormaps, &ColorMapper::up= date); = delayFocusTimer =3D 0; = @@ -163,13 +158,6 @@ Workspace::Workspace(const QString &sessionKey) = RuleBook::create(this)->load(); = - // Call this before XSelectInput() on the root window - startup =3D new KStartupInfo( - KStartupInfo::DisableKWinModule | KStartupInfo::AnnounceSilenceCha= nges, this); - - // Select windowmanager privileges - selectWmInputEventMask(); - ScreenEdges::create(this); = // VirtualDesktopManager needs to be created prior to init shortcuts @@ -196,12 +184,6 @@ Workspace::Workspace(const QString &sessionKey) = new DBusInterface(this); = - // Compatibility - int32_t data =3D 1; - - xcb_change_property(connection(), XCB_PROP_MODE_APPEND, rootWindow(), = atoms->kwin_running, - atoms->kwin_running, 32, 1, &data); - Outline::create(this); = initShortcuts(); @@ -211,11 +193,6 @@ Workspace::Workspace(const QString &sessionKey) = void Workspace::init() { - if (kwinApp()->operationMode() =3D=3D Application::OperationModeX11) { - m_wasUserInteractionFilter.reset(new WasUserInteractionX11Filter); - m_movingClientFilter.reset(new MovingClientX11Filter); - } - updateXTime(); // Needed for proper initialization of user_time in Cli= ent ctor KSharedConfigPtr config =3D kwinApp()->config(); kwinApp()->createScreens(); Screens *screens =3D Screens::self(); @@ -239,12 +216,6 @@ void Workspace::init() connect(options, SIGNAL(separateScreenFocusChanged(bool)), focusChain,= SLOT(setSeparateScreenFocus(bool))); focusChain->setSeparateScreenFocus(options->isSeparateScreenFocus()); = - const uint32_t nullFocusValues[] =3D {true}; - m_nullFocus.reset(new Xcb::Window(QRect(-1, -1, 1, 1), XCB_WINDOW_CLAS= S_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, nullFocusValues)); - m_nullFocus->map(); - - RootInfo *rootInfo =3D RootInfo::create(); - // create VirtualDesktopManager and perform dependency injection VirtualDesktopManager *vds =3D VirtualDesktopManager::self(); connect(vds, SIGNAL(desktopsRemoved(uint)), SLOT(moveClientsFromRemove= dDesktops())); @@ -252,7 +223,6 @@ void Workspace::init() connect(vds, SIGNAL(currentChanged(uint,uint)), SLOT(slotCurrentDeskto= pChanged(uint,uint))); vds->setNavigationWrappingAround(options->isRollOverDesktops()); connect(options, SIGNAL(rollOverDesktopsChanged(bool)), vds, SLOT(setN= avigationWrappingAround(bool))); - vds->setRootInfo(rootInfo); vds->setConfig(config); = // Now we know how many desktops we'll have, thus we initialize the po= sitioning object @@ -262,10 +232,6 @@ void Workspace::init() vds->load(); vds->updateLayout(); = - // Extra NETRootInfo instance in Client mode is needed to get the valu= es of the properties - NETRootInfo client_info(connection(), NET::ActiveWindow | NET::Current= Desktop); - if (!qApp->isSessionRestored()) - m_initialDesktop =3D client_info.currentDesktop(); if (!VirtualDesktopManager::self()->setCurrent(m_initialDesktop)) VirtualDesktopManager::self()->setCurrent(1); = @@ -284,87 +250,8 @@ void Workspace::init() this, SLOT(reconfigure())); = active_client =3D NULL; - rootInfo->setActiveWindow(None); - focusToNull(); - if (!qApp->isSessionRestored()) - ++block_focus; // Because it will be set below - - { - // Begin updates blocker block - StackingUpdatesBlocker blocker(this); - - Xcb::Tree tree(rootWindow()); - xcb_window_t *wins =3D xcb_query_tree_children(tree.data()); - - QVector windowAttributes(tree->children_len= ); - QVector windowGeometries(tree->children_len); - - // Request the attributes and geometries of all toplevel windows - for (int i =3D 0; i < tree->children_len; i++) { - windowAttributes[i] =3D Xcb::WindowAttributes(wins[i]); - windowGeometries[i] =3D Xcb::WindowGeometry(wins[i]); - } - - // Get the replies - for (int i =3D 0; i < tree->children_len; i++) { - Xcb::WindowAttributes attr(windowAttributes.at(i)); - - if (attr.isNull()) { - continue; - } - - if (attr->override_redirect) { - if (attr->map_state =3D=3D XCB_MAP_STATE_VIEWABLE && - attr->_class !=3D XCB_WINDOW_CLASS_INPUT_ONLY) - // ### This will request the attributes again - createUnmanaged(wins[i]); - } else if (attr->map_state !=3D XCB_MAP_STATE_UNMAPPED) { - if (Application::wasCrash()) { - fixPositionAfterCrash(wins[i], windowGeometries.at(i).= data()); - } - - // ### This will request the attributes again - createClient(wins[i], true); - } - } - - // Propagate clients, will really happen at the end of the updates= blocker block - updateStackingOrder(true); = - saveOldScreenSizes(); - updateClientArea(); - - // NETWM spec says we have to set it to (0,0) if we don't support = it - NETPoint* viewports =3D new NETPoint[VirtualDesktopManager::self()= ->count()]; - rootInfo->setDesktopViewport(VirtualDesktopManager::self()->count(= ), *viewports); - delete[] viewports; - QRect geom; - for (int i =3D 0; i < screens->count(); i++) { - geom |=3D screens->geometry(i); - } - NETSize desktop_geometry; - desktop_geometry.width =3D geom.width(); - desktop_geometry.height =3D geom.height(); - rootInfo->setDesktopGeometry(desktop_geometry); - setShowingDesktop(false); - - } // End updates blocker block - - AbstractClient* new_active_client =3D nullptr; - if (!qApp->isSessionRestored()) { - --block_focus; - new_active_client =3D findClient(Predicate::WindowMatch, client_in= fo.activeWindow()); - } - if (new_active_client =3D=3D NULL - && activeClient() =3D=3D NULL && should_get_focus.count() =3D= =3D 0) { - // No client activated in manage() - if (new_active_client =3D=3D NULL) - new_active_client =3D topClientOnDesktop(VirtualDesktopManager= ::self()->current(), -1); - if (new_active_client =3D=3D NULL && !desktops.isEmpty()) - new_active_client =3D findDesktop(true, VirtualDesktopManager:= :self()->current()); - } - if (new_active_client !=3D NULL) - activateClient(new_active_client); + initWithX11(); = Scripting::create(this); = @@ -461,6 +348,141 @@ void Workspace::init() // TODO: ungrabXServer() } = +void Workspace::initWithX11() +{ + if (!kwinApp()->x11Connection()) { + connect(kwinApp(), &Application::x11ConnectionChanged, this, &Work= space::initWithX11, Qt::UniqueConnection); + return; + } + disconnect(kwinApp(), &Application::x11ConnectionChanged, this, &Works= pace::initWithX11); + + atoms->retrieveHelpers(); + + // first initialize the extensions + Xcb::Extensions::self(); + ColorMapper *colormaps =3D new ColorMapper(this); + connect(this, &Workspace::clientActivated, colormaps, &ColorMapper::up= date); + + // Call this before XSelectInput() on the root window + startup =3D new KStartupInfo( + KStartupInfo::DisableKWinModule | KStartupInfo::AnnounceSilenceCha= nges, this); + + // Select windowmanager privileges + selectWmInputEventMask(); + + // Compatibility + int32_t data =3D 1; + + xcb_change_property(connection(), XCB_PROP_MODE_APPEND, rootWindow(), = atoms->kwin_running, + atoms->kwin_running, 32, 1, &data); + + if (kwinApp()->operationMode() =3D=3D Application::OperationModeX11) { + m_wasUserInteractionFilter.reset(new WasUserInteractionX11Filter); + m_movingClientFilter.reset(new MovingClientX11Filter); + } + updateXTime(); // Needed for proper initialization of user_time in Cli= ent ctor + + const uint32_t nullFocusValues[] =3D {true}; + m_nullFocus.reset(new Xcb::Window(QRect(-1, -1, 1, 1), XCB_WINDOW_CLAS= S_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, nullFocusValues)); + m_nullFocus->map(); + + RootInfo *rootInfo =3D RootInfo::create(); + VirtualDesktopManager::self()->setRootInfo(rootInfo); + + // TODO: only in X11 mode + // Extra NETRootInfo instance in Client mode is needed to get the valu= es of the properties + NETRootInfo client_info(connection(), NET::ActiveWindow | NET::Current= Desktop); + if (!qApp->isSessionRestored()) + m_initialDesktop =3D client_info.currentDesktop(); + if (!VirtualDesktopManager::self()->setCurrent(m_initialDesktop)) + VirtualDesktopManager::self()->setCurrent(1); + + // TODO: better value + rootInfo->setActiveWindow(None); + focusToNull(); + + if (!qApp->isSessionRestored()) + ++block_focus; // Because it will be set below + + { + // Begin updates blocker block + StackingUpdatesBlocker blocker(this); + + Xcb::Tree tree(rootWindow()); + xcb_window_t *wins =3D xcb_query_tree_children(tree.data()); + + QVector windowAttributes(tree->children_len= ); + QVector windowGeometries(tree->children_len); + + // Request the attributes and geometries of all toplevel windows + for (int i =3D 0; i < tree->children_len; i++) { + windowAttributes[i] =3D Xcb::WindowAttributes(wins[i]); + windowGeometries[i] =3D Xcb::WindowGeometry(wins[i]); + } + + // Get the replies + for (int i =3D 0; i < tree->children_len; i++) { + Xcb::WindowAttributes attr(windowAttributes.at(i)); + + if (attr.isNull()) { + continue; + } + + if (attr->override_redirect) { + if (attr->map_state =3D=3D XCB_MAP_STATE_VIEWABLE && + attr->_class !=3D XCB_WINDOW_CLASS_INPUT_ONLY) + // ### This will request the attributes again + createUnmanaged(wins[i]); + } else if (attr->map_state !=3D XCB_MAP_STATE_UNMAPPED) { + if (Application::wasCrash()) { + fixPositionAfterCrash(wins[i], windowGeometries.at(i).= data()); + } + + // ### This will request the attributes again + createClient(wins[i], true); + } + } + + // Propagate clients, will really happen at the end of the updates= blocker block + updateStackingOrder(true); + + saveOldScreenSizes(); + updateClientArea(); + + // NETWM spec says we have to set it to (0,0) if we don't support = it + NETPoint* viewports =3D new NETPoint[VirtualDesktopManager::self()= ->count()]; + rootInfo->setDesktopViewport(VirtualDesktopManager::self()->count(= ), *viewports); + delete[] viewports; + QRect geom; + for (int i =3D 0; i < screens()->count(); i++) { + geom |=3D screens()->geometry(i); + } + NETSize desktop_geometry; + desktop_geometry.width =3D geom.width(); + desktop_geometry.height =3D geom.height(); + rootInfo->setDesktopGeometry(desktop_geometry); + setShowingDesktop(false); + + } // End updates blocker block + + // TODO: only on X11? + AbstractClient* new_active_client =3D nullptr; + if (!qApp->isSessionRestored()) { + --block_focus; + new_active_client =3D findClient(Predicate::WindowMatch, client_in= fo.activeWindow()); + } + if (new_active_client =3D=3D NULL + && activeClient() =3D=3D NULL && should_get_focus.count() =3D= =3D 0) { + // No client activated in manage() + if (new_active_client =3D=3D NULL) + new_active_client =3D topClientOnDesktop(VirtualDesktopManager= ::self()->current(), -1); + if (new_active_client =3D=3D NULL && !desktops.isEmpty()) + new_active_client =3D findDesktop(true, VirtualDesktopManager:= :self()->current()); + } + if (new_active_client !=3D NULL) + activateClient(new_active_client); +} + Workspace::~Workspace() { blockStackingUpdates(true); @@ -1207,7 +1229,9 @@ bool Workspace::checkStartupNotification(xcb_window_t= w, KStartupInfoId &id, KSt */ void Workspace::focusToNull() { - m_nullFocus->focus(); + if (m_nullFocus) { + m_nullFocus->focus(); + } } = void Workspace::setShowingDesktop(bool showing) diff --git a/workspace.h b/workspace.h index e70cf7daf..012210d95 100644 --- a/workspace.h +++ b/workspace.h @@ -494,6 +494,7 @@ Q_SIGNALS: = private: void init(); + void initWithX11(); void initShortcuts(); template void initShortcut(const QString &actionName, const QString &descriptio= n, const QKeySequence &shortcut,