From dfd111d3e59f744da21538adf54a121a56b38364 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Thu, 14 May 2015 20:26:59 -0500 Subject: [PATCH] 5.3.0-3 - test candidate SM fixes (reviewboard#123580,kde#341930) - move libkdeinit bits out of -libs - move dbus interface xml to runtime pkg - drop %config from knsrc files - enable wayland support (f21+) - .spec cosmetics --- kwin-session_management_review123580.patch | 314 +++++++++++++++++++++ kwin.spec | 44 ++- 2 files changed, 343 insertions(+), 15 deletions(-) create mode 100644 kwin-session_management_review123580.patch diff --git a/kwin-session_management_review123580.patch b/kwin-session_management_review123580.patch new file mode 100644 index 0000000..88110fd --- /dev/null +++ b/kwin-session_management_review123580.patch @@ -0,0 +1,314 @@ +diff --git a/main.h b/main.h +index 276cf78..532f54c 100644 +--- a/main.h ++++ b/main.h +@@ -184,6 +184,9 @@ protected: + bool notify(QObject* o, QEvent* e); + static void crashHandler(int signal); + ++protected: ++ QString m_originalSessionKey; ++ + private Q_SLOTS: + void resetCrashesCount(); + +diff --git a/main.cpp b/main.cpp +index fa6e373..6a91e3b 100644 +--- a/main.cpp ++++ b/main.cpp +@@ -42,7 +42,6 @@ along with this program. If not, see . + #include + // Qt + #include +-#include + #include + #include + #include +@@ -372,7 +371,7 @@ void Application::createWorkspace() + // critical startup section where x errors cause kwin to abort. + + // create workspace. +- (void) new Workspace(isSessionRestored()); ++ (void) new Workspace(m_originalSessionKey); + emit workspaceCreated(); + } + +diff --git a/main_x11.cpp b/main_x11.cpp +index c50aad2..b1c4a40 100644 +--- a/main_x11.cpp ++++ b/main_x11.cpp +@@ -146,6 +146,11 @@ void ApplicationX11::performStartup() + Application::setX11ScreenNumber(QX11Info::appScreen()); + } + ++ // QSessionManager for some reason triggers a very early commitDataRequest ++ // and updates the key - before we create the workspace and load the session ++ // data -> store and pass to the workspace constructor ++ m_originalSessionKey = sessionKey(); ++ + owner.reset(new KWinSelectionOwner(Application::x11ScreenNumber())); + connect(owner.data(), &KSelectionOwner::failedToClaimOwnership, []{ + fputs(i18n("kwin: unable to claim manager selection, another wm running? (try using --replace)\n").toLocal8Bit().constData(), stderr); +@@ -291,10 +296,6 @@ KWIN_EXPORT int kdemain(int argc, char * argv[]) + + a.start(); + +-#warning SessionManager needs porting +-#if KWIN_QT5_PORTING +- KWin::SessionManager weAreIndeed; +-#endif + KWin::SessionSaveDoneHelper helper; + + return a.exec(); +diff --git a/sm.h b/sm.h +index cc63aa3..529187d 100644 +--- a/sm.h ++++ b/sm.h +@@ -25,9 +25,6 @@ along with this program. If not, see . + #include + #include + #include +-#if KWIN_QT5_PORTING +-#include +-#endif + #include + #include + +@@ -101,16 +98,6 @@ private: + SmcConn conn; + }; + +-#if KWIN_QT5_PORTING +-class SessionManager +- : public KSessionManager +-{ +-public: +- virtual bool saveState(QSessionManager& sm); +- virtual bool commitData(QSessionManager& sm); +-}; +-#endif +- + } // namespace + + #endif +diff --git a/sm.cpp b/sm.cpp +index 0e3e735..2098b7f 100644 +--- a/sm.cpp ++++ b/sm.cpp +@@ -36,8 +36,26 @@ along with this program. If not, see . + namespace KWin + { + +-#if KWIN_QT5_PORTING +-bool SessionManager::saveState(QSessionManager& sm) ++static bool gs_sessionManagerIsKSMServer = false; ++static KConfig *sessionConfig(QString id, QString key) ++{ ++ static KConfig *config = nullptr; ++ static QString lastId; ++ static QString lastKey; ++ static QString pattern = QString(QLatin1String("session/%1_%2_%3")).arg(qApp->applicationName()); ++ if (id != lastId || key != lastKey) { ++ delete config; ++ config = nullptr; ++ } ++ lastId = id; ++ lastKey = key; ++ if (!config) { ++ config = new KConfig(pattern.arg(id).arg(key), KConfig::SimpleConfig); ++ } ++ return config; ++} ++ ++void Workspace::saveState(QSessionManager &sm) + { + // If the session manager is ksmserver, save stacking + // order, active window, active desktop etc. in phase 1, +@@ -45,37 +63,27 @@ bool SessionManager::saveState(QSessionManager& sm) + // before the WM finishes phase 1. Saving in phase 2 is + // too late, as possible user interaction may change some things. + // Phase2 is still needed though (ICCCM 5.2) +-#if KWIN_QT5_PORTING +- char* sm_vendor = SmcVendor(static_cast< SmcConn >(sm.handle())); +- bool ksmserver = qstrcmp(sm_vendor, "KDE") == 0; +- free(sm_vendor); +-#else +-#warning need to figure out whether the used SessionManager is ksmserver +- bool ksmserver = false; +-#endif ++ KConfig *config = sessionConfig(sm.sessionId(), sm.sessionKey()); + if (!sm.isPhase2()) { +- Workspace::self()->sessionSaveStarted(); +- if (ksmserver) // save stacking order etc. before "save file?" etc. dialogs change it +- Workspace::self()->storeSession(kapp->sessionConfig(), SMSavePhase0); ++ KConfigGroup cg(config, "Session"); ++ cg.writeEntry("AllowsInteraction", sm.allowsInteraction()); ++ sessionSaveStarted(); ++ if (gs_sessionManagerIsKSMServer) // save stacking order etc. before "save file?" etc. dialogs change it ++ storeSession(config, SMSavePhase0); + sm.release(); // Qt doesn't automatically release in this case (bug?) + sm.requestPhase2(); +- return true; ++ return; + } +- Workspace::self()->storeSession(kapp->sessionConfig(), ksmserver ? SMSavePhase2 : SMSavePhase2Full); +-#if KWIN_QT5_PORTING +- kapp->sessionConfig()->sync(); +-#endif +- return true; ++ storeSession(config, gs_sessionManagerIsKSMServer ? SMSavePhase2 : SMSavePhase2Full); ++ config->sync(); + } + + // I bet this is broken, just like everywhere else in KDE +-bool SessionManager::commitData(QSessionManager& sm) ++void Workspace::commitData(QSessionManager &sm) + { + if (!sm.isPhase2()) +- Workspace::self()->sessionSaveStarted(); +- return true; ++ sessionSaveStarted(); + } +-#endif + + // Workspace + +@@ -194,18 +202,18 @@ void Workspace::storeSubSession(const QString &name, QSet sessionIds + + \sa storeSession() + */ +-void Workspace::loadSessionInfo() ++void Workspace::loadSessionInfo(const QString &key) + { ++ // NOTICE: qApp->sessionKey() is outdated when this gets invoked ++ // the key parameter is cached from the application constructor. + session.clear(); +-#if KWIN_QT5_PORTING +- KConfigGroup cg(kapp->sessionConfig(), "Session"); +- ++ KConfigGroup cg(sessionConfig(qApp->sessionId(), key), "Session"); + addSessionInfo(cg); +-#endif + } + + void Workspace::addSessionInfo(KConfigGroup &cg) + { ++ m_initialDesktop = cg.readEntry(QStringLiteral("desktop"), 1); + int count = cg.readEntry("count", 0); + int active_client = cg.readEntry("active", 0); + for (int i = 1; i <= count; i++) { +@@ -408,9 +416,8 @@ static void shutdown_cancelled(SmcConn conn_P, SmPointer ptr) + + void SessionSaveDoneHelper::saveDone() + { +-#if KWIN_QT5_PORTING +- Workspace::self()->sessionSaveDone(); +-#endif ++ if (Workspace::self()) ++ Workspace::self()->sessionSaveDone(); + } + + SessionSaveDoneHelper::SessionSaveDoneHelper() +@@ -433,6 +440,15 @@ SessionSaveDoneHelper::SessionSaveDoneHelper() + free(id); + if (conn == NULL) + return; // no SM ++ ++ // detect ksmserver ++ // NOTICE: no idea whether the assumptions about it in Workspace::saveState() ++ // still hold for KF5/Plasma 5 ++#warning assuming special behavior in ksmserver to be still present in KF5 ++ char* vendor = SmcVendor(conn); ++ gs_sessionManagerIsKSMServer = qstrcmp(vendor, "KDE") == 0; ++ free(vendor); ++ + // set the required properties, mostly dummy values + SmPropValue propvalue[ 5 ]; + SmProp props[ 5 ]; +diff --git a/workspace.h b/workspace.h +index 4acefb4..84d6edf 100644 +--- a/workspace.h ++++ b/workspace.h +@@ -62,7 +62,7 @@ class KWIN_EXPORT Workspace : public QObject + { + Q_OBJECT + public: +- explicit Workspace(bool restore = false); ++ explicit Workspace(const QString &sessionKey = QString()); + virtual ~Workspace(); + + static Workspace* self() { +@@ -431,6 +431,10 @@ private Q_SLOTS: + void slotDesktopCountChanged(uint previousCount, uint newCount); + void slotCurrentDesktopChanged(uint oldDesktop, uint newDesktop); + ++ // session management ++ void saveState(QSessionManager &sm); ++ void commitData(QSessionManager &sm); ++ + Q_SIGNALS: + /** + * Emitted after the Workspace has setup the complete initialization process. +@@ -503,7 +507,8 @@ private: + QWidget* active_popup; + Client* active_popup_client; + +- void loadSessionInfo(); ++ int m_initialDesktop; ++ void loadSessionInfo(const QString &key); + void addSessionInfo(KConfigGroup &cg); + + QList session; +diff --git a/workspace.cpp b/workspace.cpp +index 09ae9a2..9e71494 100644 +--- a/workspace.cpp ++++ b/workspace.cpp +@@ -99,12 +99,13 @@ void ColorMapper::update() + + Workspace* Workspace::_self = 0; + +-Workspace::Workspace(bool restore) ++Workspace::Workspace(const QString &sessionKey) + : QObject(0) + , m_compositor(NULL) + // Unsorted + , active_popup(NULL) + , active_popup_client(NULL) ++ , m_initialDesktop(1) + , active_client(0) + , last_active_client(0) + , most_recently_raised(0) +@@ -155,8 +156,10 @@ Workspace::Workspace(bool restore) + + delayFocusTimer = 0; + +- if (restore) +- loadSessionInfo(); ++ if (!sessionKey.isEmpty()) ++ loadSessionInfo(sessionKey); ++ connect(qApp, SIGNAL(commitDataRequest(QSessionManager&)), SLOT(commitData(QSessionManager&))); ++ connect(qApp, SIGNAL(saveStateRequest(QSessionManager&)), SLOT(saveState(QSessionManager&))); + + RuleBook::create(this)->load(); + +@@ -260,18 +263,9 @@ void Workspace::init() + + // Extra NETRootInfo instance in Client mode is needed to get the values of the properties + NETRootInfo client_info(connection(), NET::ActiveWindow | NET::CurrentDesktop); +- int initial_desktop; + if (!qApp->isSessionRestored()) +- initial_desktop = client_info.currentDesktop(); +- else { +-#if KWIN_QT5_PORTING +- KConfigGroup group(kapp->sessionConfig(), "Session"); +- initial_desktop = group.readEntry("desktop", 1); +-#else +- initial_desktop = 1; +-#endif +- } +- if (!VirtualDesktopManager::self()->setCurrent(initial_desktop)) ++ m_initialDesktop = client_info.currentDesktop(); ++ if (!VirtualDesktopManager::self()->setCurrent(m_initialDesktop)) + VirtualDesktopManager::self()->setCurrent(1); + + reconfigureTimer.setSingleShot(true); diff --git a/kwin.spec b/kwin.spec index 0addc00..7b488fd 100644 --- a/kwin.spec +++ b/kwin.spec @@ -1,11 +1,13 @@ # Whether to build experimental Wayland support # NOTE: Does not build on F20 due to too old Wayland and requires kf5-kwayland, # which is not available in Fedora yet -%global wayland 0 +%if 0%{?fedora} > 20 +%global wayland 1 +%endif Name: kwin Version: 5.3.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: KDE Window manager # all sources are effectively GPLv2+, except for: @@ -22,6 +24,10 @@ URL: https://projects.kde.org/projects/kde/workspace/kwin %endif Source0: http://download.kde.org/%{stable}/plasma/%{version}/%{name}-%{version}.tar.xz +## upstreamable patches +# session management, https://git.reviewboard.kde.org/r/123580/ +Patch1: kwin-session_management_review123580.patch + # Base BuildRequires: kf5-rpm-macros BuildRequires: extra-cmake-modules @@ -136,17 +142,18 @@ BuildArch: noarch %prep -%setup -q -n %{name}-%{version} +%autosetup -n %{name}-%{version} -p1 %build -mkdir -p %{_target_platform} +mkdir %{_target_platform} pushd %{_target_platform} %{cmake_kf5} .. popd make %{?_smp_mflags} -C %{_target_platform} + %install make install/fast DESTDIR=%{buildroot} -C %{_target_platform} %find_lang kwin5 --with-qt --with-kde --all-name @@ -170,6 +177,8 @@ fi %files -f kwin5.lang %{_bindir}/kwin %{_bindir}/kwin_x11 +%{_kf5_libdir}/libkdeinit5_kwin_x11.so +%{_kf5_libdir}/libkdeinit5_kwin_rules_dialog.so %{_datadir}/kwin %{_kf5_qtplugindir}/*.so %{_kf5_qtplugindir}/kwin @@ -184,24 +193,22 @@ fi %{_kf5_datadir}/kservicetypes5/*.desktop %{_kf5_datadir}/knotifications5/kwin.notifyrc %{_kf5_datadir}/config.kcfg/kwin.kcfg -%{_datadir}/icons/hicolor/*/apps/* -%config %{_sysconfdir}/xdg/*.knsrc +%{_datadir}/icons/hicolor/*/apps/kwin.* +%{_datadir}/dbus-1/interfaces/*.xml +# note: these are for reference (to express config defaults), they are +# not config files themselves (so don't use %%config tag) +%{_sysconfdir}/xdg/*.knsrc %if 0%{wayland} %files wayland %{_bindir}/kwin_wayland +%{_kf5_libdir}/libkdeinit5_kwin_wayland.so %endif - %post libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig %files libs -%{_kf5_libdir}/libkdeinit5_kwin_x11.so -%if 0%{wayland} -%{_kf5_libdir}/libkdeinit5_kwin_wayland.so -%endif -%{_kf5_libdir}/libkdeinit5_kwin_rules_dialog.so %{_libdir}/libkwin.so.* %{_libdir}/libkwinxrenderutils.so.* %{_libdir}/libkwineffects.so.* @@ -210,19 +217,26 @@ fi %files devel %{_libdir}/cmake/KWinDBusInterface -%{_datadir}/dbus-1/interfaces/*.xml %{_libdir}/libkwinxrenderutils.so %{_libdir}/libkwineffects.so %{_libdir}/libkwinglutils.so %{_libdir}/libkwin4_effect_builtins.so -%{_includedir}/*.h +%{_includedir}/kwin*.h %files doc %doc COMPLIANCE COPYING COPYING.DOC HACKING README -%{_docdir}/HTML/en/* +%{_docdir}/HTML/en/kcontrol/ %changelog +* Thu May 14 2015 Rex Dieter - 5.3.0-3 +- test candidate SM fixes (reviewboard#123580,kde#341930) +- move libkdeinit bits out of -libs +- move dbus interface xml to runtime pkg +- drop %%config from knsrc files +- enable wayland support (f21+) +- .spec cosmetics + * Wed Apr 29 2015 Jan Grulich - 5.3.0-2 - BR xcb-util-cursor-devel