Port one of session management connections state to a custom API
Summary: Currently kwin opens a second ICE connection to ksmserver in order to tell the state of kwin's whether we're logging out and saving clients or not. This requires that kwin launches after ksmserver to have the connection which is a dependency I want to break. Practically this code is already ksmserver specific as it relies on some custom code that sends the first saveState request to kwin first. Instead we can replace it with a bespoke IPC over DBus and siplify the code both end. This will allow several other future enhancements that we want with regards to handling the session state, as well as make an effort platform agnostic session management, as well as cleaning up some complex code. Ksmserver calls into kwin, rather than having kwin watch ksmserver state to allow us make sure it's race free. Reviewers: #kwin, zzag Reviewed By: #kwin, zzag Subscribers: romangg, zzag, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D24862
This commit is contained in:
parent
cf2791803f
commit
ec610fd7ed
11 changed files with 114 additions and 209 deletions
|
@ -549,6 +549,7 @@ qt5_add_dbus_adaptor(kwin_KDEINIT_SRCS org.kde.kwin.ColorCorrect.xml colorcorrec
|
|||
qt5_add_dbus_adaptor(kwin_KDEINIT_SRCS ${kwin_effects_dbus_xml} effects.h KWin::EffectsHandlerImpl)
|
||||
qt5_add_dbus_adaptor(kwin_KDEINIT_SRCS org.kde.kwin.OrientationSensor.xml orientation_sensor.h KWin::OrientationSensor)
|
||||
qt5_add_dbus_adaptor(kwin_KDEINIT_SRCS org.kde.KWin.VirtualDesktopManager.xml dbusinterface.h KWin::VirtualDesktopManagerDBusInterface)
|
||||
qt5_add_dbus_adaptor(kwin_KDEINIT_SRCS org.kde.KWin.Session.xml sm.h KWin::SessionManager)
|
||||
|
||||
qt5_add_dbus_interface(kwin_KDEINIT_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/kf5_org.freedesktop.ScreenSaver.xml screenlocker_interface)
|
||||
qt5_add_dbus_interface(kwin_KDEINIT_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/org.kde.screensaver.xml kscreenlocker_interface)
|
||||
|
|
|
@ -558,7 +558,7 @@ bool Workspace::allowClientActivation(const KWin::AbstractClient *c, xcb_timesta
|
|||
if (time == -1U)
|
||||
time = c->userTime();
|
||||
int level = c->rules()->checkFSP(options->focusStealingPreventionLevel());
|
||||
if (session_saving && level <= FSP::Medium) { // <= normal
|
||||
if (sessionManager()->state() == SessionState::Saving && level <= FSP::Medium) { // <= normal
|
||||
return true;
|
||||
}
|
||||
AbstractClient* ac = mostRecentlyActivatedClient();
|
||||
|
@ -635,7 +635,7 @@ bool Workspace::allowClientActivation(const KWin::AbstractClient *c, xcb_timesta
|
|||
bool Workspace::allowFullClientRaising(const KWin::AbstractClient *c, xcb_timestamp_t time)
|
||||
{
|
||||
int level = c->rules()->checkFSP(options->focusStealingPreventionLevel());
|
||||
if (session_saving && level <= 2) { // <= normal
|
||||
if (sessionManager()->state() == SessionState::Saving && level <= 2) { // <= normal
|
||||
return true;
|
||||
}
|
||||
AbstractClient* ac = mostRecentlyActivatedClient();
|
||||
|
|
|
@ -121,7 +121,7 @@ void Activities::toggleClientOnActivity(X11Client *c, const QString &activity, b
|
|||
bool Activities::start(const QString &id)
|
||||
{
|
||||
Workspace *ws = Workspace::self();
|
||||
if (ws->sessionSaving()) {
|
||||
if (ws->sessionManager()->state() == SessionState::Saving) {
|
||||
return false; //ksmserver doesn't queue requests (yet)
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ bool Activities::start(const QString &id)
|
|||
|
||||
bool Activities::stop(const QString &id)
|
||||
{
|
||||
if (Workspace::self()->sessionSaving()) {
|
||||
if (Workspace::self()->sessionManager()->state() == SessionState::Saving) {
|
||||
return false; //ksmserver doesn't queue requests (yet)
|
||||
//FIXME what about session *loading*?
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ bool Activities::stop(const QString &id)
|
|||
void Activities::reallyStop(const QString &id)
|
||||
{
|
||||
Workspace *ws = Workspace::self();
|
||||
if (ws->sessionSaving())
|
||||
if (ws->sessionManager()->state() == SessionState::Saving)
|
||||
return; //ksmserver doesn't queue requests (yet)
|
||||
|
||||
qCDebug(KWIN_CORE) << id;
|
||||
|
|
|
@ -138,6 +138,16 @@ enum class SwipeDirection {
|
|||
Right
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the state of the session running outside kwin
|
||||
* Under Plasma this is managed by ksmserver
|
||||
*/
|
||||
enum class SessionState {
|
||||
Normal,
|
||||
Saving,
|
||||
Quitting
|
||||
};
|
||||
|
||||
inline
|
||||
KWIN_EXPORT xcb_connection_t *connection()
|
||||
{
|
||||
|
|
|
@ -480,9 +480,6 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
|
|||
|
||||
a.start();
|
||||
|
||||
KWin::SessionSaveDoneHelper helper;
|
||||
Q_UNUSED(helper); // The sessionsavedonehelper opens a side channel to the smserver,
|
||||
// listens for events and talks to it, so it needs to be created.
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
|
|
|
@ -432,7 +432,8 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
|
|||
init_minimize = false; // SELI TODO: Even e.g. for NET::Utility?
|
||||
}
|
||||
// If a dialog is shown for minimized window, minimize it too
|
||||
if (!init_minimize && isTransient() && mainClients().count() > 0 && !workspace()->sessionSaving()) {
|
||||
if (!init_minimize && isTransient() && mainClients().count() > 0 &&
|
||||
workspace()->sessionManager()->state() != SessionState::Saving) {
|
||||
bool visible_parent = false;
|
||||
// Use allMainClients(), to include also main clients of group transients
|
||||
// that have been optimized out in X11Client::checkGroupTransients()
|
||||
|
@ -532,13 +533,15 @@ bool X11Client::manage(xcb_window_t w, bool isMapped)
|
|||
else
|
||||
allow = workspace()->allowClientActivation(this, userTime(), false);
|
||||
|
||||
const bool isSessionSaving = workspace()->sessionManager()->state() == SessionState::Saving;
|
||||
|
||||
// If session saving, force showing new windows (i.e. "save file?" dialogs etc.)
|
||||
// also force if activation is allowed
|
||||
if( !isOnCurrentDesktop() && !isMapped && !session && ( allow || workspace()->sessionSaving() ))
|
||||
if( !isOnCurrentDesktop() && !isMapped && !session && ( allow || isSessionSaving ))
|
||||
VirtualDesktopManager::self()->setCurrent( desktop());
|
||||
|
||||
// If the window is on an inactive activity during session saving, temporarily force it to show.
|
||||
if( !isMapped && !session && workspace()->sessionSaving() && !isOnCurrentActivity()) {
|
||||
if( !isMapped && !session && isSessionSaving && !isOnCurrentActivity()) {
|
||||
setSessionActivityOverride( true );
|
||||
foreach( AbstractClient* c, mainClients()) {
|
||||
if (X11Client *mc = dynamic_cast<X11Client *>(c)) {
|
||||
|
|
15
org.kde.KWin.Session.xml
Normal file
15
org.kde.KWin.Session.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.kde.KWin.Session">
|
||||
<method name="setState">
|
||||
<!-- Sets state of the session should be one of:
|
||||
0 = normal
|
||||
1 = saving
|
||||
2= quitting
|
||||
-->
|
||||
<arg name="state" type="u" direction="in" />
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
|
210
sm.cpp
210
sm.cpp
|
@ -29,14 +29,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "workspace.h"
|
||||
#include "x11client.h"
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QSocketNotifier>
|
||||
#include <QSessionManager>
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include "sessionadaptor.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
static bool gs_sessionManagerIsKSMServer = false;
|
||||
static KConfig *sessionConfig(QString id, QString key)
|
||||
{
|
||||
static KConfig *config = nullptr;
|
||||
|
@ -83,6 +83,8 @@ static NET::WindowType txtToWindowType(const char* txt)
|
|||
|
||||
void Workspace::saveState(QSessionManager &sm)
|
||||
{
|
||||
bool sessionManagerIsKSMServer = QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.ksmserver").value();
|
||||
|
||||
// If the session manager is ksmserver, save stacking
|
||||
// order, active window, active desktop etc. in phase 1,
|
||||
// as ksmserver assures no interaction will be done
|
||||
|
@ -93,15 +95,14 @@ void Workspace::saveState(QSessionManager &sm)
|
|||
if (!sm.isPhase2()) {
|
||||
KConfigGroup cg(config, "Session");
|
||||
cg.writeEntry("AllowsInteraction", sm.allowsInteraction());
|
||||
sessionSaveStarted();
|
||||
if (gs_sessionManagerIsKSMServer) // save stacking order etc. before "save file?" etc. dialogs change it
|
||||
if (sessionManagerIsKSMServer) // save stacking order etc. before "save file?" etc. dialogs change it
|
||||
storeSession(config, SMSavePhase0);
|
||||
config->markAsClean(); // don't write Phase #1 data to disk
|
||||
sm.release(); // Qt doesn't automatically release in this case (bug?)
|
||||
sm.requestPhase2();
|
||||
return;
|
||||
}
|
||||
storeSession(config, gs_sessionManagerIsKSMServer ? SMSavePhase2 : SMSavePhase2Full);
|
||||
storeSession(config, sessionManagerIsKSMServer ? SMSavePhase2 : SMSavePhase2Full);
|
||||
config->sync();
|
||||
|
||||
// inform the smserver on how to clean-up after us
|
||||
|
@ -111,13 +112,6 @@ void Workspace::saveState(QSessionManager &sm)
|
|||
}
|
||||
}
|
||||
|
||||
// I bet this is broken, just like everywhere else in KDE
|
||||
void Workspace::commitData(QSessionManager &sm)
|
||||
{
|
||||
if (!sm.isPhase2())
|
||||
sessionSaveStarted();
|
||||
}
|
||||
|
||||
// Workspace
|
||||
|
||||
/**
|
||||
|
@ -361,158 +355,54 @@ SessionInfo* Workspace::takeSessionInfo(X11Client *c)
|
|||
return realInfo;
|
||||
}
|
||||
|
||||
// KWin's focus stealing prevention causes problems with user interaction
|
||||
// during session save, as it prevents possible dialogs from getting focus.
|
||||
// Therefore it's temporarily disabled during session saving. Start of
|
||||
// session saving can be detected in SessionManager::saveState() above,
|
||||
// but Qt doesn't have API for saying when session saved finished (either
|
||||
// successfully, or was canceled). Therefore, create another connection
|
||||
// to session manager, that will provide this information.
|
||||
// Similarly the remember feature of window-specific settings should be disabled
|
||||
// during KDE shutdown when windows may move e.g. because of Kicker going away
|
||||
// (struts changing). When session saving starts, it can be cancelled, in which
|
||||
// case the shutdown_cancelled callback is invoked, or it's a checkpoint that
|
||||
// is immediatelly followed by save_complete, or finally it's a shutdown that
|
||||
// is immediatelly followed by die callback. So getting save_yourself with shutdown
|
||||
// set disables window-specific settings remembering, getting shutdown_cancelled
|
||||
// re-enables, otherwise KWin will go away after die.
|
||||
static void save_yourself(SmcConn conn_P, SmPointer ptr, int, Bool shutdown, int, Bool)
|
||||
SessionManager::SessionManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
|
||||
if (conn_P != session->connection())
|
||||
new SessionAdaptor(this);
|
||||
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Session"), this);
|
||||
}
|
||||
|
||||
SessionManager::~SessionManager()
|
||||
{
|
||||
}
|
||||
|
||||
SessionState SessionManager::state() const
|
||||
{
|
||||
return m_sessionState;
|
||||
}
|
||||
|
||||
void SessionManager::setState(uint state)
|
||||
{
|
||||
switch (state) {
|
||||
case 0:
|
||||
setState(SessionState::Saving);
|
||||
break;
|
||||
case 1:
|
||||
setState(SessionState::Quitting);
|
||||
break;
|
||||
default:
|
||||
setState(SessionState::Normal);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionManager::setState(SessionState state)
|
||||
{
|
||||
if (state == m_sessionState) {
|
||||
return;
|
||||
if (shutdown)
|
||||
}
|
||||
// If we're starting to save a session
|
||||
if (state == SessionState::Saving) {
|
||||
RuleBook::self()->setUpdatesDisabled(true);
|
||||
SmcSaveYourselfDone(conn_P, True);
|
||||
}
|
||||
|
||||
static void die(SmcConn conn_P, SmPointer ptr)
|
||||
{
|
||||
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
|
||||
if (conn_P != session->connection())
|
||||
return;
|
||||
// session->saveDone(); we will quit anyway
|
||||
session->close();
|
||||
}
|
||||
|
||||
static void save_complete(SmcConn conn_P, SmPointer ptr)
|
||||
{
|
||||
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
|
||||
if (conn_P != session->connection())
|
||||
return;
|
||||
session->saveDone();
|
||||
}
|
||||
|
||||
static void shutdown_cancelled(SmcConn conn_P, SmPointer ptr)
|
||||
{
|
||||
SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr);
|
||||
if (conn_P != session->connection())
|
||||
return;
|
||||
RuleBook::self()->setUpdatesDisabled(false); // re-enable
|
||||
// no need to differentiate between successful finish and cancel
|
||||
session->saveDone();
|
||||
}
|
||||
|
||||
void SessionSaveDoneHelper::saveDone()
|
||||
{
|
||||
if (Workspace::self())
|
||||
Workspace::self()->sessionSaveDone();
|
||||
}
|
||||
|
||||
SessionSaveDoneHelper::SessionSaveDoneHelper()
|
||||
{
|
||||
SmcCallbacks calls;
|
||||
calls.save_yourself.callback = save_yourself;
|
||||
calls.save_yourself.client_data = reinterpret_cast< SmPointer >(this);
|
||||
calls.die.callback = die;
|
||||
calls.die.client_data = reinterpret_cast< SmPointer >(this);
|
||||
calls.save_complete.callback = save_complete;
|
||||
calls.save_complete.client_data = reinterpret_cast< SmPointer >(this);
|
||||
calls.shutdown_cancelled.callback = shutdown_cancelled;
|
||||
calls.shutdown_cancelled.client_data = reinterpret_cast< SmPointer >(this);
|
||||
char* id = nullptr;
|
||||
char err[ 11 ];
|
||||
conn = SmcOpenConnection(nullptr, nullptr, 1, 0,
|
||||
SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask
|
||||
| SmcShutdownCancelledProcMask, &calls, nullptr, &id, 10, err);
|
||||
if (id != nullptr)
|
||||
free(id);
|
||||
if (conn == nullptr)
|
||||
return; // no SM
|
||||
|
||||
// detect ksmserver
|
||||
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 ];
|
||||
propvalue[ 0 ].length = sizeof(unsigned char);
|
||||
unsigned char value0 = SmRestartNever; // so that this extra SM connection doesn't interfere
|
||||
propvalue[ 0 ].value = &value0;
|
||||
props[ 0 ].name = const_cast< char* >(SmRestartStyleHint);
|
||||
props[ 0 ].type = const_cast< char* >(SmCARD8);
|
||||
props[ 0 ].num_vals = 1;
|
||||
props[ 0 ].vals = &propvalue[ 0 ];
|
||||
struct passwd* entry = getpwuid(geteuid());
|
||||
propvalue[ 1 ].length = entry != nullptr ? strlen(entry->pw_name) : 0;
|
||||
propvalue[ 1 ].value = (SmPointer)(entry != nullptr ? entry->pw_name : "");
|
||||
props[ 1 ].name = const_cast< char* >(SmUserID);
|
||||
props[ 1 ].type = const_cast< char* >(SmARRAY8);
|
||||
props[ 1 ].num_vals = 1;
|
||||
props[ 1 ].vals = &propvalue[ 1 ];
|
||||
propvalue[ 2 ].length = 0;
|
||||
propvalue[ 2 ].value = (SmPointer)("");
|
||||
props[ 2 ].name = const_cast< char* >(SmRestartCommand);
|
||||
props[ 2 ].type = const_cast< char* >(SmLISTofARRAY8);
|
||||
props[ 2 ].num_vals = 1;
|
||||
props[ 2 ].vals = &propvalue[ 2 ];
|
||||
propvalue[ 3 ].length = strlen("kwinsmhelper");
|
||||
propvalue[ 3 ].value = (SmPointer)"kwinsmhelper";
|
||||
props[ 3 ].name = const_cast< char* >(SmProgram);
|
||||
props[ 3 ].type = const_cast< char* >(SmARRAY8);
|
||||
props[ 3 ].num_vals = 1;
|
||||
props[ 3 ].vals = &propvalue[ 3 ];
|
||||
propvalue[ 4 ].length = 0;
|
||||
propvalue[ 4 ].value = (SmPointer)("");
|
||||
props[ 4 ].name = const_cast< char* >(SmCloneCommand);
|
||||
props[ 4 ].type = const_cast< char* >(SmLISTofARRAY8);
|
||||
props[ 4 ].num_vals = 1;
|
||||
props[ 4 ].vals = &propvalue[ 4 ];
|
||||
SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] };
|
||||
SmcSetProperties(conn, 5, p);
|
||||
notifier = new QSocketNotifier(IceConnectionNumber(SmcGetIceConnection(conn)),
|
||||
QSocketNotifier::Read, this);
|
||||
connect(notifier, SIGNAL(activated(int)), SLOT(processData()));
|
||||
}
|
||||
|
||||
SessionSaveDoneHelper::~SessionSaveDoneHelper()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void SessionSaveDoneHelper::close()
|
||||
{
|
||||
if (conn != nullptr) {
|
||||
delete notifier;
|
||||
SmcCloseConnection(conn, 0, nullptr);
|
||||
}
|
||||
conn = nullptr;
|
||||
}
|
||||
|
||||
void SessionSaveDoneHelper::processData()
|
||||
{
|
||||
if (conn != nullptr)
|
||||
IceProcessMessages(SmcGetIceConnection(conn), nullptr, nullptr);
|
||||
}
|
||||
|
||||
void Workspace::sessionSaveDone()
|
||||
{
|
||||
session_saving = false;
|
||||
foreach (X11Client *c, clients) {
|
||||
c->setSessionActivityOverride(false);
|
||||
// If we're ending a save session due to either completion or cancellation
|
||||
if (m_sessionState == SessionState::Saving) {
|
||||
RuleBook::self()->setUpdatesDisabled(false);
|
||||
Workspace::self()->forEachClient([](X11Client *client) {
|
||||
client->setSessionActivityOverride(false);
|
||||
});
|
||||
}
|
||||
m_sessionState = state;
|
||||
emit stateChanged();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
44
sm.h
44
sm.h
|
@ -28,16 +28,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <netwm_def.h>
|
||||
#include <QRect>
|
||||
|
||||
#include <X11/SM/SMlib.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
class QSocketNotifier;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class X11Client;
|
||||
|
||||
class SessionManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SessionManager(QObject *parent);
|
||||
~SessionManager() override;
|
||||
|
||||
SessionState state() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void stateChanged();
|
||||
|
||||
public Q_SLOTS: // DBus API
|
||||
void setState(uint state);
|
||||
|
||||
private:
|
||||
void setState(SessionState state);
|
||||
SessionState m_sessionState;
|
||||
};
|
||||
|
||||
struct SessionInfo {
|
||||
QByteArray sessionId;
|
||||
QByteArray windowRole;
|
||||
|
@ -77,25 +92,6 @@ enum SMSavePhase {
|
|||
SMSavePhase2Full // complete saving in phase2, there was no phase 0
|
||||
};
|
||||
|
||||
class KWIN_EXPORT SessionSaveDoneHelper
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SessionSaveDoneHelper();
|
||||
~SessionSaveDoneHelper() override;
|
||||
SmcConn connection() const {
|
||||
return conn;
|
||||
}
|
||||
void saveDone();
|
||||
void close();
|
||||
private Q_SLOTS:
|
||||
void processData();
|
||||
private:
|
||||
QSocketNotifier* notifier;
|
||||
SmcConn conn;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -118,7 +118,6 @@ Workspace::Workspace(const QString &sessionKey)
|
|||
, force_restacking(false)
|
||||
, showing_desktop(false)
|
||||
, was_user_interaction(false)
|
||||
, session_saving(false)
|
||||
, block_focus(0)
|
||||
, m_userActionsMenu(new UserActionsMenu(this))
|
||||
, client_keys_dialog(nullptr)
|
||||
|
@ -128,6 +127,7 @@ Workspace::Workspace(const QString &sessionKey)
|
|||
, startup(nullptr)
|
||||
, set_active_client_recursion(0)
|
||||
, block_stacking_updates(0)
|
||||
, m_sessionManager(new SessionManager(this))
|
||||
{
|
||||
// If KWin was already running it saved its configuration after loosing the selection -> Reread
|
||||
QFuture<void> reparseConfigFuture = QtConcurrent::run(options, &Options::reparseConfiguration);
|
||||
|
@ -156,7 +156,6 @@ Workspace::Workspace(const QString &sessionKey)
|
|||
|
||||
if (!sessionKey.isEmpty())
|
||||
loadSessionInfo(sessionKey);
|
||||
connect(qApp, &QGuiApplication::commitDataRequest, this, &Workspace::commitData);
|
||||
connect(qApp, &QGuiApplication::saveStateRequest, this, &Workspace::saveState);
|
||||
|
||||
RuleBook::create(this)->load();
|
||||
|
|
18
workspace.h
18
workspace.h
|
@ -244,6 +244,8 @@ public:
|
|||
|
||||
void stackScreenEdgesUnderOverrideRedirect();
|
||||
|
||||
SessionManager *sessionManager() const;
|
||||
|
||||
public:
|
||||
QPoint cascadeOffset(const AbstractClient *c) const;
|
||||
|
||||
|
@ -339,11 +341,8 @@ public:
|
|||
bool globalShortcutsDisabled() const;
|
||||
void disableGlobalShortcutsForClient(bool disable);
|
||||
|
||||
void sessionSaveStarted();
|
||||
void sessionSaveDone();
|
||||
void setWasUserInteraction();
|
||||
bool wasUserInteraction() const;
|
||||
bool sessionSaving() const;
|
||||
|
||||
int packPositionLeft(const AbstractClient *client, int oldX, bool leftEdge) const;
|
||||
int packPositionRight(const AbstractClient *client, int oldX, bool rightEdge) const;
|
||||
|
@ -492,7 +491,6 @@ private Q_SLOTS:
|
|||
|
||||
// session management
|
||||
void saveState(QSessionManager &sm);
|
||||
void commitData(QSessionManager &sm);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
|
@ -616,7 +614,7 @@ private:
|
|||
|
||||
bool was_user_interaction;
|
||||
QScopedPointer<X11EventFilter> m_wasUserInteractionFilter;
|
||||
bool session_saving;
|
||||
|
||||
int session_active_client;
|
||||
int session_desktop;
|
||||
|
||||
|
@ -666,6 +664,7 @@ private:
|
|||
QList<X11EventFilter *> m_genericEventFilters;
|
||||
QScopedPointer<X11EventFilter> m_movingClientFilter;
|
||||
|
||||
SessionManager *m_sessionManager;
|
||||
private:
|
||||
friend bool performTransiencyCheck();
|
||||
friend Workspace *workspace();
|
||||
|
@ -742,14 +741,9 @@ inline bool Workspace::wasUserInteraction() const
|
|||
return was_user_interaction;
|
||||
}
|
||||
|
||||
inline void Workspace::sessionSaveStarted()
|
||||
inline SessionManager *Workspace::sessionManager() const
|
||||
{
|
||||
session_saving = true;
|
||||
}
|
||||
|
||||
inline bool Workspace::sessionSaving() const
|
||||
{
|
||||
return session_saving;
|
||||
return m_sessionManager;
|
||||
}
|
||||
|
||||
inline bool Workspace::showingDesktop() const
|
||||
|
|
Loading…
Reference in a new issue