mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
ksmserver: drop it and move session initialization to plasma-desktop
everything except the actual session management, second time ksmserver starts crashing as I work on something for no reason and is time for it to be done anew as there were quite some unsafe bits in it Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
bb574694b1
commit
3e5dfaa22b
46 changed files with 322 additions and 4297 deletions
|
@ -263,7 +263,6 @@ add_subdirectory(systemsettings)
|
|||
|
||||
# core apps
|
||||
add_subdirectory(kwin)
|
||||
add_subdirectory(ksmserver)
|
||||
add_subdirectory(kscreensaver)
|
||||
|
||||
add_subdirectory(qguiplatformplugin_kde)
|
||||
|
|
|
@ -107,7 +107,6 @@ void KCMInit::runModules( int phase )
|
|||
continue; // Skip
|
||||
}
|
||||
|
||||
// see ksmserver's README for the description of the phases
|
||||
QVariant vphase = service->property("X-KDE-Init-Phase", QVariant::Int );
|
||||
int libphase = 1;
|
||||
if( vphase.isValid() )
|
||||
|
|
|
@ -91,7 +91,7 @@ CfgWm::CfgWm(QWidget *parent)
|
|||
connect(wmCombo,SIGNAL(activated(int)),this,SLOT(checkConfigureWm()));
|
||||
connect(configureButton,SIGNAL(clicked()),this,SLOT(configureWm()));
|
||||
|
||||
KGlobal::dirs()->addResourceType( "windowmanagers", "data", "ksmserver/windowmanagers" );
|
||||
KGlobal::dirs()->addResourceType("windowmanagers", "data", "plasma/windowmanagers");
|
||||
}
|
||||
|
||||
CfgWm::~CfgWm()
|
||||
|
@ -111,7 +111,7 @@ void CfgWm::defaults()
|
|||
|
||||
void CfgWm::load(KConfig *)
|
||||
{
|
||||
KConfig cfg("ksmserverrc", KConfig::NoGlobals);
|
||||
KConfig cfg("plasmarc", KConfig::NoGlobals);
|
||||
KConfigGroup c( &cfg, "General");
|
||||
loadWMs(c.readEntry("windowManager", "kwin"));
|
||||
emit changed(false);
|
||||
|
@ -124,7 +124,7 @@ void CfgWm::save(KConfig *)
|
|||
|
||||
bool CfgWm::saveAndConfirm()
|
||||
{
|
||||
KConfig cfg("ksmserverrc", KConfig::NoGlobals);
|
||||
KConfig cfg("plasmarc", KConfig::NoGlobals);
|
||||
KConfigGroup c( &cfg, "General");
|
||||
c.writeEntry("windowManager", currentWm());
|
||||
emit changed(false);
|
||||
|
@ -134,8 +134,8 @@ bool CfgWm::saveAndConfirm()
|
|||
if (tryWmLaunch()) {
|
||||
oldwm = currentWm();
|
||||
cfg.sync();
|
||||
QDBusInterface ksmserver("org.kde.ksmserver", "/KSMServer");
|
||||
ksmserver.call(QDBus::NoBlock, "wmChanged");
|
||||
QDBusInterface plasma("org.kde.plasma-desktop", "/App", "local.PlasmaApp");
|
||||
plasma.call(QDBus::NoBlock, "wmChanged");
|
||||
KMessageBox::information(
|
||||
window(),
|
||||
i18n("A new window manager is running.\n"
|
||||
|
@ -269,12 +269,6 @@ void CfgWm::loadWMs(const QString ¤t)
|
|||
continue;
|
||||
if (!file.tryExec())
|
||||
continue;
|
||||
QString testexec = file.desktopGroup().readEntry("X-KDE-WindowManagerTestExec");
|
||||
if (!testexec.isEmpty()) {
|
||||
if (QProcess::execute(testexec) != 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
QString name = file.readName();
|
||||
if (name.isEmpty())
|
||||
continue;
|
||||
|
|
|
@ -7,5 +7,5 @@ install(
|
|||
metacity.desktop
|
||||
openbox.desktop
|
||||
xfwm4.desktop
|
||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/ksmserver/windowmanagers
|
||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/plasma/windowmanagers
|
||||
)
|
||||
|
|
|
@ -10,15 +10,6 @@ Exec - required, the command to execute to launch the window manager.
|
|||
|
||||
TryExec - optional.
|
||||
|
||||
X-KDE-WindowManagerTestExec - optional, a command that will be run and if
|
||||
the exit code is not 0, the window manager won't be used (can be used
|
||||
e.g. to detect that a window manager which requires compositing support
|
||||
cannot be run on systems without such support).
|
||||
|
||||
X-KDE-WindowManagerId - optional, the name under which the window manager
|
||||
registers with the session manager (if different from the name
|
||||
of the .desktop file)
|
||||
|
||||
X-KDE-WindowManagerConfigure - optional, the command to run to configure
|
||||
the window manager
|
||||
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
project(ksmserver)
|
||||
|
||||
add_definitions(-DKDE_DEFAULT_DEBUG_AREA=1218)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/libs
|
||||
# for kworkspace_export.h
|
||||
${CMAKE_BINARY_DIR}/libs/kworkspace
|
||||
)
|
||||
|
||||
add_subdirectory(kcm)
|
||||
|
||||
check_library_exists(ICE _IceTransNoListen "" HAVE__ICETRANSNOLISTEN)
|
||||
configure_file(config-ksmserver.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-ksmserver.h)
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set(ksmserver_SRCS
|
||||
main.cpp
|
||||
server.cpp
|
||||
shutdowndlg.cpp
|
||||
startup.cpp
|
||||
shutdown.cpp
|
||||
client.cpp
|
||||
)
|
||||
|
||||
set(kcminit_adaptor ${CMAKE_SOURCE_DIR}/kcminit/main.h)
|
||||
set(kcminit_xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.KCMinit.xml)
|
||||
qt4_generate_dbus_interface(${kcminit_adaptor} ${kcminit_xml})
|
||||
|
||||
qt4_add_dbus_interface( ksmserver_SRCS ${kcminit_xml} kcminit_interface )
|
||||
|
||||
# This is actually now disabled, because OrgKDEKlauncherInterface is also provided
|
||||
# by kdecore, it is not autogenerated and is not binary compatible with a currently
|
||||
# generated version, thus at certain circumstances leading to strange crashes.
|
||||
# This should be fixed for KDE5.
|
||||
# KLauchner.xml is installed by kdelibs, so it is in KDE4_DBUS_INTERFACES_INSTALL_DIR
|
||||
# set(klauncher_xml ${KDE4_DBUS_INTERFACES_INSTALL_DIR}/org.kde.KLauncher.xml)
|
||||
# qt4_add_dbus_interface( ksmserver_SRCS ${klauncher_xml} klauncher_interface )
|
||||
|
||||
qt4_add_dbus_adaptor(ksmserver_SRCS org.kde.KSMServerInterface.xml server.h KSMServer)
|
||||
|
||||
add_executable(ksmserver ${ksmserver_SRCS})
|
||||
|
||||
target_link_libraries(ksmserver
|
||||
KDE4::plasma
|
||||
KDE4::kdeui
|
||||
KDE4::kio
|
||||
KDE4::solid
|
||||
${QT_QTDECLARATIVE_LIBRARY}
|
||||
${X11_LIBRARIES}
|
||||
kworkspace
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS ksmserver
|
||||
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set(kcheckrunning_SRCS
|
||||
kcheckrunning.cpp
|
||||
)
|
||||
|
||||
add_executable(kcheckrunning ${kcheckrunning_SRCS})
|
||||
target_link_libraries(kcheckrunning ${X11_LIBRARIES})
|
||||
|
||||
install(
|
||||
TARGETS kcheckrunning
|
||||
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install(
|
||||
FILES org.kde.KSMServerInterface.xml
|
||||
DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR}
|
||||
)
|
|
@ -1,48 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
******************************************************************/
|
||||
|
||||
#ifndef KSMSERVER_INTERFACE_H
|
||||
#define KSMSERVER_INTERFACE_H
|
||||
|
||||
#include <dcopobject.h>
|
||||
|
||||
class KSMServerInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.KSMServerInterface")
|
||||
|
||||
public Q_SLOTS:
|
||||
Q_SCRIPTABLE void logout(int, int );
|
||||
Q_SCRIPTABLE QStringList sessionList();
|
||||
|
||||
Q_SCRIPTABLE QString currentSession();
|
||||
Q_SCRIPTABLE void saveCurrentSession();
|
||||
Q_SCRIPTABLE void saveCurrentSessionAs( QString );
|
||||
|
||||
Q_SCRIPTABLE void suspendStartup( QString );
|
||||
Q_SCRIPTABLE void resumeStartup( QString );
|
||||
Q_SCRIPTABLE void wmChanged();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/bash
|
||||
$XGETTEXT *.cpp -o $podir/ksmserver.pot
|
159
ksmserver/README
159
ksmserver/README
|
@ -1,159 +0,0 @@
|
|||
KDE session manager (ksmserver)
|
||||
--------------------------------
|
||||
|
||||
Matthias Ettrich <ettrich@kde.org>
|
||||
Lubos Lunak <l.lunak@kde.org>
|
||||
|
||||
ksmserver is KDE's session management server. It talks the
|
||||
standard X11R6 session management protocol (XSMP). Thus, in theory,
|
||||
it should be compatible with all session managment compliant X11R6
|
||||
applications. Unfortunately, there aren't that many of them. To be
|
||||
precise, I have never seen a single commercial application that
|
||||
supports it and even within the official X11R6 distribution, 'xclock'
|
||||
is the only exception. Nevertheless we've chosen to support XSMP
|
||||
despites the complexity of the protocol in order to provide KDE users
|
||||
more interoperability with applications that were not explicitely
|
||||
written with KDE in mind. XSMP, as an official X standard, promised to
|
||||
be more likely to be supported by third parties than even a superior
|
||||
KDE-specific protocol. Let's see whether we were right and more
|
||||
applications will actually talk XSMP. At least all KDE applications do
|
||||
now.
|
||||
|
||||
Here's a short overview on how session management works.
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
Starting the server
|
||||
KDE startup sequence
|
||||
Establishing the connection
|
||||
Authorization
|
||||
Requesting a shutdown
|
||||
|
||||
|
||||
Starting the server
|
||||
-------------------
|
||||
|
||||
The server is usually started from the 'startkde' script. It supports the following options:
|
||||
|
||||
-r, --restore Restores the previous session if available
|
||||
-w, --windowmanager <wm> Starts 'wm' in case no other window manager is
|
||||
participating in the session. Default is 'kwin'
|
||||
|
||||
The default 'startkde' launches 'ksmserver --restore'. The
|
||||
'windowmanager' option is useful for users that prefer a window
|
||||
manager other than kwin. Since the window manager has to participate
|
||||
in the session (it has to remember window positions and states), it is
|
||||
usually restarted when the session is restored. To be *really* sure
|
||||
that this happens, even if the wm might have crashed during the
|
||||
previous session, ksmserver ensures that. The option specifies, which
|
||||
windowmanager shall be launched for sure. But again: if the stored
|
||||
session contains a window manager, the restored one will be used, not
|
||||
the specified one. As a special feature, ksmserver always starts the
|
||||
specified window manager first, which results in a much nicer startup
|
||||
sequence (less flashy).
|
||||
|
||||
KDE startup sequence
|
||||
--------------------
|
||||
|
||||
Ksmserver controls the second part of the KDE startup sequence,
|
||||
after it gets control from the startkde script, which controls
|
||||
the first part of the startup sequence. All code related to startup
|
||||
should be in startup.cpp and going down in that source file should
|
||||
follow the startup order (but note that this is just a documentation
|
||||
which may get outdated, so in case of doubts the source wins ;) ).
|
||||
|
||||
The startkde script launches kcminit, which performs initialization done by
|
||||
kcontrol modules. There are three kcminit phases, 0, 1 and 2, controlled
|
||||
by X-KDE-Init-Phase= in the .desktop file, which defaults to 1. Phase 0 kcminit
|
||||
modules should be only those that really need to be run early in the startup
|
||||
process. After executing phase 0 modules kcminit returns and waits.
|
||||
|
||||
When ksmserver is launched, the first thing it does is launching
|
||||
the window manager, as the WM is necessary before any windows are possibly
|
||||
shown. When the WM is ready, ksmserver launchers kded. Kded loads autoloaded
|
||||
kded modules, i.e. those that have X-KDE-Kded-autoload=true in .desktop
|
||||
files. The exact way autoloading works is controlled by X-KDE-Kded-phase=,
|
||||
which may be 0, 1 or 2 (the default). Kded phase 0 means the module is
|
||||
always loaded by kded, even outside of KDE session. It should used only
|
||||
by kded modules which must be always running. Kded phase 1 modules are
|
||||
loaded right after kded startup, but only during KDE startup, i.e. it is
|
||||
for modules that are always needed by the KDE session. Phase 2 modules
|
||||
will be loaded later. [More information about kded modules could be
|
||||
found in kdelibs/kded/HOWTO]
|
||||
|
||||
The next thing ksmserver does is to tell klauncher to perform autostart
|
||||
phase 0 ($KDEHOME/share/autostart). There are 3 autostart phases, 0, 1 and 2,
|
||||
defined by X-KDE-autostart-phase, defaulting to 2. Phase 0 is reserved only
|
||||
for the actual visible base components of KDE, i.e. Plasma, in order to make
|
||||
the startup appear visually faster. Plasma uses D-Bus calls suspendStartup()
|
||||
and resumeStartup() to make ksmserver stay waiting for autostart phase 0
|
||||
until Plasma is ready (note: suspendStartup() needs to be called before
|
||||
the application registers with ksmserver, i.e. before KApplication ctor is called).
|
||||
|
||||
Next step is telling the waiting kcminit to perform phase 1 - all kcminit
|
||||
modules that should be executed before KDE startup is considered done.
|
||||
After that ksmserver tells klauncher to perform autostart phase 1,
|
||||
i.e. launching normal components of KDE that should be available right
|
||||
after KDE startup, and after this session restore is performed,
|
||||
i.e. launching all applications that were running during last session
|
||||
saving (usually logout).
|
||||
|
||||
By this time KDE session is considered to be more or less ready and
|
||||
ksmserver does the knotify startkde event (i.e. plays the login sound).
|
||||
It also tells klauncher to perform autostart phase 2, kded to load all
|
||||
remaining autoload (i.e. kded phase 2) modules, kcminit to execute
|
||||
kcminit phase 2 (kcontrol modules that do initialization that can wait,
|
||||
like launching daemons) and it itself executes the user Autostart folder.
|
||||
|
||||
Technical note: There's a reason why kded modules and items in autostart
|
||||
default to the latest phase. Before you explicitly use a different phase,
|
||||
read and understand what's above. You should also consider whether something
|
||||
really needs to be launched during KDE startup and can't be loaded on-demand
|
||||
when really needed. Abusing the phases will result in public spanking
|
||||
for making KDE startup slower.
|
||||
|
||||
|
||||
Establishing the connection
|
||||
---------------------------
|
||||
|
||||
As required by the XSMP specification, the session management server
|
||||
propagates its network address in the SESSION_MANAGER environment
|
||||
variable. Probably not the best way to do it, but it's the way it
|
||||
is. All KDE (and plain Qt) applications simply read this variable and
|
||||
try to establish a connection to an XSMP server at this address. If
|
||||
the variable is undefined, nothing happens.
|
||||
|
||||
This means, if you want to start a program that should not participate
|
||||
in the session, simply undefine SESSION_MANAGER in your terminal
|
||||
window and launch the application. If you want to see an application
|
||||
desparately trying to connect to something, try setting it to some
|
||||
bogus value.
|
||||
|
||||
In addition, ksmserver propagates both its network address and its
|
||||
process id in /run/user/<uid>/KSMserver_$DISPLAY. A utility function
|
||||
KWorkSpace::propagateSessionManager() reads this setting and sets
|
||||
SESSION_MANAGER accordingly, so that child processes can pick it up.
|
||||
The function is called by clients that are started outside the session
|
||||
(i.e. before ksmserver is started), but want to launch other processes
|
||||
that should participate in the session.
|
||||
|
||||
Authorization
|
||||
-------------
|
||||
|
||||
XSMP is built on top of the Inter Client Exchange (ICE) protocol,
|
||||
which comes standard as a part of X11R6 and later.
|
||||
Authorization is done using 'iceauth', with MIT-MAGIC-COOKIE as used
|
||||
by X. In order to be able to access the session management server, you
|
||||
need to be able to read ~/.ICEauthority. For security reasons, we do
|
||||
not provide any host-based authorization.
|
||||
|
||||
|
||||
Requesting a shutdown
|
||||
---------------------
|
||||
|
||||
If an application wants to request a shutdown (i.e. a logout), it does
|
||||
this via an SmcRequestSaveYourself message to the server. In KDE, a
|
||||
utility function KWorkSpace::requestShutDown() does exactly
|
||||
this. It's for example called by KDE's panel or by the context menu of
|
||||
the desktop.
|
|
@ -1,185 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
Copyright 2005 Lubos Lunak <l.lunak@kde.org>
|
||||
|
||||
relatively small extensions by Oswald Buddenhagen <ob6@inf.tu-dresden.de>
|
||||
|
||||
some code taken from the dcopserver (part of the KDE libraries), which is
|
||||
Copyright 1999 Matthias Ettrich <ettrich@kde.org>
|
||||
Copyright 1999 Preston Brown <pbrown@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "config-unix.h"
|
||||
|
||||
#include "client.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <kglobal.h>
|
||||
#include <krandom.h>
|
||||
#include "server.h"
|
||||
|
||||
extern KSMServer* the_server;
|
||||
|
||||
KSMClient::KSMClient( SmsConn conn)
|
||||
{
|
||||
smsConn = conn;
|
||||
id = 0;
|
||||
resetState();
|
||||
}
|
||||
|
||||
KSMClient::~KSMClient()
|
||||
{
|
||||
foreach( SmProp *prop, properties )
|
||||
SmFreeProperty( prop );
|
||||
if (id) free((void*)id);
|
||||
}
|
||||
|
||||
SmProp* KSMClient::property( const char* name ) const
|
||||
{
|
||||
foreach ( SmProp *prop, properties ) {
|
||||
if ( qstrcmp( prop->name, name ) == 0)
|
||||
return prop;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KSMClient::resetState()
|
||||
{
|
||||
saveYourselfDone = false;
|
||||
pendingInteraction = false;
|
||||
waitForPhase2 = false;
|
||||
wasPhase2 = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This fakes SmsGenerateClientID() in case we can't read our own hostname.
|
||||
* In this case SmsGenerateClientID() returns NULL, but we really want a
|
||||
* client ID, so we fake one.
|
||||
*/
|
||||
K_GLOBAL_STATIC(QString, my_addr)
|
||||
char * safeSmsGenerateClientID( SmsConn /*c*/ )
|
||||
{
|
||||
// Causes delays with misconfigured network :-/.
|
||||
// char *ret = SmsGenerateClientID(c);
|
||||
char* ret = NULL;
|
||||
if (!ret) {
|
||||
if (my_addr->isEmpty()) {
|
||||
// qWarning("Can't get own host name. Your system is severely misconfigured\n");
|
||||
|
||||
/* Faking our IP address, the 0 below is "unknown" address format
|
||||
(1 would be IP, 2 would be DEC-NET format) */
|
||||
char hostname[ 256 ];
|
||||
::memset(hostname, '\0', sizeof(hostname));
|
||||
if( ::gethostname( hostname, 255 ) != 0 )
|
||||
my_addr->sprintf("0%.8x", KRandom::random());
|
||||
else {
|
||||
// create some kind of hash for the hostname
|
||||
int addr[ 4 ] = { 0, 0, 0, 0 };
|
||||
int pos = 0;
|
||||
for( unsigned int i = 0;
|
||||
i < strlen( hostname );
|
||||
++i, ++pos )
|
||||
addr[ pos % 4 ] += hostname[ i ];
|
||||
*my_addr = "0";
|
||||
for( int i = 0;
|
||||
i < 4;
|
||||
++i )
|
||||
*my_addr += QString::number( addr[ i ], 16 );
|
||||
}
|
||||
}
|
||||
/* Needs to be malloc(), to look the same as libSM */
|
||||
ret = (char *)malloc(1+my_addr->length()+13+10+4+1 + /*safeness*/ 10);
|
||||
static int sequence = 0;
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
sprintf(ret, "1%s%.13ld%.10d%.4d", my_addr->toLatin1().constData(), (long)time(NULL),
|
||||
getpid(), sequence);
|
||||
sequence = (sequence + 1) % 10000;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void KSMClient::registerClient( const char* previousId )
|
||||
{
|
||||
id = previousId;
|
||||
if ( !id )
|
||||
id = safeSmsGenerateClientID( smsConn );
|
||||
SmsRegisterClientReply( smsConn, (char*) id );
|
||||
SmsSaveYourself( smsConn, SmSaveLocal, false, SmInteractStyleNone, false );
|
||||
SmsSaveComplete( smsConn );
|
||||
the_server->clientRegistered( previousId );
|
||||
}
|
||||
|
||||
|
||||
QString KSMClient::program() const
|
||||
{
|
||||
SmProp* p = property( SmProgram );
|
||||
if ( !p || qstrcmp( p->type, SmARRAY8) != 0 || p->num_vals < 1)
|
||||
return QString();
|
||||
return QLatin1String( (const char*) p->vals[0].value );
|
||||
}
|
||||
|
||||
QStringList KSMClient::restartCommand() const
|
||||
{
|
||||
QStringList result;
|
||||
SmProp* p = property( SmRestartCommand );
|
||||
if ( !p || qstrcmp( p->type, SmLISTofARRAY8) != 0 || p->num_vals < 1)
|
||||
return result;
|
||||
for ( int i = 0; i < p->num_vals; i++ )
|
||||
result +=QLatin1String( (const char*) p->vals[i].value );
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList KSMClient::discardCommand() const
|
||||
{
|
||||
QStringList result;
|
||||
SmProp* p = property( SmDiscardCommand );
|
||||
if ( !p || qstrcmp( p->type, SmLISTofARRAY8) != 0 || p->num_vals < 1)
|
||||
return result;
|
||||
for ( int i = 0; i < p->num_vals; i++ )
|
||||
result +=QLatin1String( (const char*) p->vals[i].value );
|
||||
return result;
|
||||
}
|
||||
|
||||
int KSMClient::restartStyleHint() const
|
||||
{
|
||||
SmProp* p = property( SmRestartStyleHint );
|
||||
if ( !p || qstrcmp( p->type, SmCARD8) != 0 || p->num_vals < 1)
|
||||
return SmRestartIfRunning;
|
||||
return *((unsigned char*)p->vals[0].value);
|
||||
}
|
||||
|
||||
QString KSMClient::userId() const
|
||||
{
|
||||
SmProp* p = property( SmUserID );
|
||||
if ( !p || qstrcmp( p->type, SmARRAY8) != 0 || p->num_vals < 1)
|
||||
return QString();
|
||||
return QLatin1String( (const char*) p->vals[0].value );
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kworkspace/kworkspace.h>
|
||||
|
||||
#include "server.h"
|
||||
|
||||
|
||||
class KSMClient
|
||||
{
|
||||
public:
|
||||
explicit KSMClient( SmsConn );
|
||||
~KSMClient();
|
||||
|
||||
void registerClient( const char* previousId = 0 );
|
||||
SmsConn connection() const { return smsConn; }
|
||||
|
||||
void resetState();
|
||||
|
||||
bool saveYourselfDone;
|
||||
bool pendingInteraction;
|
||||
bool waitForPhase2;
|
||||
bool wasPhase2;
|
||||
|
||||
QList<SmProp*> properties;
|
||||
SmProp* property( const char* name ) const;
|
||||
|
||||
QString program() const;
|
||||
QStringList restartCommand() const;
|
||||
QStringList discardCommand() const;
|
||||
int restartStyleHint() const;
|
||||
QString userId() const;
|
||||
const char* clientId() { return id ? id : ""; }
|
||||
|
||||
private:
|
||||
const char* id;
|
||||
SmsConn smsConn;
|
||||
};
|
||||
#endif
|
|
@ -1,2 +0,0 @@
|
|||
/* Define to 1 if you have the `_IceTransNoListen' function. */
|
||||
#cmakedefine HAVE__ICETRANSNOLISTEN 1
|
|
@ -1,31 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
#define KSMVendorString "KDE"
|
||||
#define KSMReleaseString "1.0"
|
||||
|
||||
#endif
|
|
@ -1,52 +0,0 @@
|
|||
/* This file is part of the KDE project
|
||||
Copyright (C) 2005 Lubos Lunak <l.lunak@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
/*
|
||||
Return 0 when KDE is running, 1 when KDE is not running but it is possible
|
||||
to connect to X, 2 when it's not possible to connect to X.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
Display* dpy = XOpenDisplay(NULL);
|
||||
if (dpy == NULL) {
|
||||
return 2;
|
||||
}
|
||||
// if ksmserver is not started yet check for the X11 atom that startkde sets
|
||||
Atom type = None;
|
||||
int format = 0;
|
||||
unsigned long nitems = 0;
|
||||
unsigned long after = 0;
|
||||
unsigned char* data = NULL;
|
||||
const int kde_full_session_status = XGetWindowProperty(
|
||||
dpy, RootWindow(dpy, 0),
|
||||
XInternAtom(dpy, "KDE_FULL_SESSION", False),
|
||||
0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &data
|
||||
);
|
||||
const bool kde_running = (kde_full_session_status == Success && data);
|
||||
if (data) {
|
||||
XFree(data);
|
||||
}
|
||||
XCloseDisplay(dpy);
|
||||
if (kde_running) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
set(kcm_smserver_PART_SRCS
|
||||
kcmsmserver.cpp
|
||||
smserverconfigimpl.cpp
|
||||
smserverconfigdlg.ui
|
||||
)
|
||||
|
||||
kde4_add_plugin(kcm_smserver ${kcm_smserver_PART_SRCS})
|
||||
|
||||
|
||||
target_link_libraries(kcm_smserver KDE4::kdeui)
|
||||
|
||||
install(TARGETS kcm_smserver DESTINATION ${KDE4_PLUGIN_INSTALL_DIR})
|
||||
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install(FILES kcmsmserver.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR})
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
$EXTRACTRC *.ui >> rc.cpp
|
||||
$XGETTEXT *.cpp -o $podir/kcmsmserver.pot
|
||||
rm -f rc.cpp
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* kcmsmserver.cpp
|
||||
* Copyright (c) 2000,2002 Oswald Buddenhagen <ossi@kde.org>
|
||||
*
|
||||
* based on kcmtaskbar.cpp
|
||||
* Copyright (c) 2000 Kurt Granroth <granroth@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
*/
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <qregexp.h>
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <klineedit.h>
|
||||
#include <kworkspace/kworkspace.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kdesktopfile.h>
|
||||
#include <kdebug.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kpluginfactory.h>
|
||||
#include <kpluginloader.h>
|
||||
#include <klocale.h>
|
||||
|
||||
#include "kcmsmserver.h"
|
||||
#include "smserverconfigimpl.h"
|
||||
|
||||
K_PLUGIN_FACTORY(SMSFactory,
|
||||
registerPlugin<SMServerConfig>();
|
||||
)
|
||||
K_EXPORT_PLUGIN(SMSFactory("kcmsmserver"))
|
||||
|
||||
SMServerConfig::SMServerConfig( QWidget *parent, const QVariantList & )
|
||||
: KCModule (SMSFactory::componentData(), parent)
|
||||
{
|
||||
setQuickHelp( i18n("<h1>Session Manager</h1>"
|
||||
" You can configure the session manager here."
|
||||
" This includes options such as whether or not the session exit (logout)"
|
||||
" should be confirmed, whether the session should be restored again when logging in"
|
||||
" and whether the computer should be automatically shut down after session"
|
||||
" exit by default."));
|
||||
|
||||
QVBoxLayout *topLayout = new QVBoxLayout(this);
|
||||
topLayout->setMargin(0);
|
||||
dialog = new SMServerConfigImpl(this);
|
||||
connect(dialog, SIGNAL(changed()), SLOT(changed()));
|
||||
|
||||
topLayout->addWidget(dialog);
|
||||
}
|
||||
|
||||
void SMServerConfig::load()
|
||||
{
|
||||
KConfigGroup c(KSharedConfig::openConfig("ksmserverrc", KConfig::NoGlobals), "General");
|
||||
dialog->confirmLogoutCheck->setChecked(c.readEntry("confirmLogout", true));
|
||||
bool en = c.readEntry("offerShutdown", true);
|
||||
dialog->offerShutdownCheck->setChecked(en);
|
||||
dialog->sdGroup->setEnabled(en);
|
||||
|
||||
QString s = c.readEntry( "loginMode" );
|
||||
if ( s == "default" )
|
||||
dialog->emptySessionRadio->setChecked(true);
|
||||
else if ( s == "restoreSavedSession" )
|
||||
dialog->savedSessionRadio->setChecked(true);
|
||||
else // "restorePreviousLogout"
|
||||
dialog->previousSessionRadio->setChecked(true);
|
||||
|
||||
switch (c.readEntry("shutdownType", int(KWorkSpace::ShutdownTypeNone))) {
|
||||
case int(KWorkSpace::ShutdownTypeHalt):
|
||||
dialog->haltRadio->setChecked(true);
|
||||
break;
|
||||
case int(KWorkSpace::ShutdownTypeReboot):
|
||||
dialog->rebootRadio->setChecked(true);
|
||||
break;
|
||||
default:
|
||||
dialog->logoutRadio->setChecked(true);
|
||||
break;
|
||||
}
|
||||
dialog->excludeLineedit->setText( c.readEntry("excludeApps"));
|
||||
|
||||
emit changed(false);
|
||||
}
|
||||
|
||||
void SMServerConfig::save()
|
||||
{
|
||||
KConfig c("ksmserverrc", KConfig::NoGlobals);
|
||||
KConfigGroup group = c.group("General");
|
||||
group.writeEntry( "confirmLogout", dialog->confirmLogoutCheck->isChecked());
|
||||
group.writeEntry( "offerShutdown", dialog->offerShutdownCheck->isChecked());
|
||||
QString s = "restorePreviousLogout";
|
||||
if ( dialog->emptySessionRadio->isChecked() )
|
||||
s = "default";
|
||||
else if ( dialog->savedSessionRadio->isChecked() )
|
||||
s = "restoreSavedSession";
|
||||
group.writeEntry( "loginMode", s );
|
||||
|
||||
group.writeEntry( "shutdownType",
|
||||
dialog->haltRadio->isChecked() ?
|
||||
int(KWorkSpace::ShutdownTypeHalt) :
|
||||
dialog->rebootRadio->isChecked() ?
|
||||
int(KWorkSpace::ShutdownTypeReboot) :
|
||||
int(KWorkSpace::ShutdownTypeNone));
|
||||
group.writeEntry("excludeApps", dialog->excludeLineedit->text());
|
||||
c.sync();
|
||||
# if 0
|
||||
// update the k menu if necessary
|
||||
QDBusInterface kicker("org.kde.kicker", "/kicker", "org.kde.kicker");
|
||||
kicker.call("configure");
|
||||
#endif
|
||||
}
|
||||
|
||||
void SMServerConfig::defaults()
|
||||
{
|
||||
dialog->previousSessionRadio->setChecked(true);
|
||||
dialog->confirmLogoutCheck->setChecked(true);
|
||||
dialog->offerShutdownCheck->setChecked(true);
|
||||
dialog->sdGroup->setEnabled(true);
|
||||
dialog->logoutRadio->setChecked(true);
|
||||
dialog->excludeLineedit->clear();
|
||||
}
|
||||
|
||||
#include "moc_kcmsmserver.cpp"
|
|
@ -1,205 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Exec=kcmshell4 kcmsmserver
|
||||
Icon=preferences-system-session
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=KCModule
|
||||
X-DocPath=kcontrol/kcmsmserver/index.html
|
||||
|
||||
X-KDE-Library=kcm_smserver
|
||||
X-KDE-ParentApp=kcontrol
|
||||
|
||||
X-KDE-System-Settings-Parent-Category=startup-and-shutdown
|
||||
|
||||
Name=Session Management
|
||||
Name[ar]=إدارة الجلسات
|
||||
Name[ast]=Xestión de sesiones
|
||||
Name[bg]=Управление на сесии
|
||||
Name[bs]=Upravljanje sesijama
|
||||
Name[ca]=Gestió de sessions
|
||||
Name[ca@valencia]=Gestió de sessions
|
||||
Name[cs]=Správa sezení
|
||||
Name[da]=Sessionshåndtering
|
||||
Name[de]=Sitzungsverwaltung
|
||||
Name[el]=Διαχείριση συνεδριών
|
||||
Name[en_GB]=Session Management
|
||||
Name[es]=Gestión de sesiones
|
||||
Name[et]=Seansihaldus
|
||||
Name[eu]=Saio-kudeaketa
|
||||
Name[fa]=مدیریت نشست
|
||||
Name[fi]=Istunnonhallinta
|
||||
Name[ga]=Bainistíocht Seisiún
|
||||
Name[gl]=Xestión de sesións
|
||||
Name[gu]=સત્ર વ્યવસ્થાપન
|
||||
Name[he]=ניהול הפעלות
|
||||
Name[hi]=सत्र प्रबंधक
|
||||
Name[hr]=Upravljanje sesijama
|
||||
Name[hu]=Munkamenetkezelés
|
||||
Name[ia]=Gestion de session
|
||||
Name[id]=Manajemen Sesi
|
||||
Name[is]=Setustjórn
|
||||
Name[kk]=Сеансты басқаруы
|
||||
Name[km]=ការគ្រប់គ្រងសម័យ
|
||||
Name[kn]=ಅಧಿವೇಶನ (ಸೆಶನ್) ವ್ಯವಸ್ಥಾಪನೆ
|
||||
Name[ko]=세션 관리
|
||||
Name[lt]=Sesijų tvarkymas
|
||||
Name[lv]=Sesiju pārvaldnieks
|
||||
Name[mr]=सत्र व्यवस्थापन
|
||||
Name[nb]=Øktbehandling
|
||||
Name[nds]=Törnpleeg
|
||||
Name[nl]=Sessiebeheer
|
||||
Name[nn]=Økthandsamar
|
||||
Name[pa]=ਸ਼ੈਸ਼ਨ ਪਰਬੰਧ
|
||||
Name[pl]=Zarządzanie sesją
|
||||
Name[pt]=Gestão de Sessões
|
||||
Name[pt_BR]=Gerenciamento de sessões
|
||||
Name[ro]=Administrarea sesiunilor
|
||||
Name[ru]=Управление сеансами
|
||||
Name[si]=සැසි කළමනාකරනය
|
||||
Name[sk]=Správa sedenia
|
||||
Name[sl]=Upravljanje s sejami
|
||||
Name[sr]=Управљање сесијама
|
||||
Name[sr@ijekavian]=Управљање сесијама
|
||||
Name[sr@ijekavianlatin]=Upravljanje sesijama
|
||||
Name[sr@latin]=Upravljanje sesijama
|
||||
Name[sv]=Sessionshantering
|
||||
Name[tg]=Мудири амалҳо
|
||||
Name[th]=จัดการวาระงาน
|
||||
Name[tr]=Oturum Yönetimi
|
||||
Name[ug]=ئەڭگىمە باشقۇرۇش
|
||||
Name[uk]=Керування сеансами
|
||||
Name[wa]=Manaedjmint des sessions
|
||||
Name[x-test]=xxSession Managementxx
|
||||
Name[zh_CN]=会话管理
|
||||
Name[zh_TW]=工作階段管理程式
|
||||
|
||||
Comment=Configure the session manager and logout settings
|
||||
Comment[af]=Konfigureer die sessie bestuurder en teken af instellings
|
||||
Comment[ar]=اضبط مدير الجلسات وإعدادات تسجيل الخروج
|
||||
Comment[ast]=Configurar el xestor de sesiones y les preferencies de zarru de sesión
|
||||
Comment[be]=Настаўленні кіраўніка сеансаў і параметраў выхаду
|
||||
Comment[be@latin]=Nałady kiraŭnika sesijaŭ i vychadu z systemy
|
||||
Comment[bg]=Настройване сесиите на системата и поведението при изход
|
||||
Comment[bn]=সেশন ম্যানেজার এবং লগ-আউট সেটিংস কনফিগার করুন
|
||||
Comment[bn_IN]=সেশান পরিচালন ব্যবস্থা ও লগ-আউটের বৈশিষ্ট্য কনফিগার করুন
|
||||
Comment[br]=Kefluniañ ar merour an dalc'hioù hag an doare mont kuit
|
||||
Comment[bs]=Podešavanje menadžera sesija i odjavljivanja
|
||||
Comment[ca]=Aquí podeu configurar el gestor de la sessió i la sortida
|
||||
Comment[ca@valencia]=Ací podeu configurar el gestor de la sessió i l'eixida
|
||||
Comment[cs]=Nastavení správce sezení a odhlašování
|
||||
Comment[csb]=Kònfigùracëjô menedżera sesëji ë nastôwów wëlogòwaniô
|
||||
Comment[cy]=Ffurfweddu'r rheolydd sesiwn a gosodiadau allgofnodi
|
||||
Comment[da]=Indstil sessionshåndterig og log ud-indstillinger
|
||||
Comment[de]=Einstellungen für Sitzungsverwaltung und Abmeldung vornehmen
|
||||
Comment[el]=Διαμορφώστε το διαχειριστή συνεδρίας και τις επιλογές αποσύνδεσης
|
||||
Comment[en_GB]=Configure the session manager and logout settings
|
||||
Comment[eo]=Agordi la seancan administrilon kaj la elsaluton
|
||||
Comment[es]=Configurar el gestor de sesiones y las preferencias de cierre de sesión
|
||||
Comment[et]=Seansihalduri ja väljalogimise seadistamine
|
||||
Comment[eu]=Konfiguratu saio-kudeatzailea eta saio-bukaeraren ezarpenak
|
||||
Comment[fa]=پیکربندی مدیر نشست و تنظیمات خروج
|
||||
Comment[fi]=Istunnonhallinnan ja uloskirjautumisen asetukset
|
||||
Comment[fy]=Hjir kinne jo it sesjebehear en ôfmeld-ynstellings fêststelle
|
||||
Comment[ga]=Cumraigh bainisteoir an tseisiúin agus socruithe logála amach
|
||||
Comment[gl]=Configura o xestor de sesións e as opcións de saída
|
||||
Comment[gu]=સત્ર વ્યવસ્થાપક અને બહાર નીકળવાની ગોઠવણીઓ રૂપરેખાંકિત કરો
|
||||
Comment[he]=הגדרת מנהל ההפעלות והגדרות היציאה
|
||||
Comment[hi]=सत्र प्रबंधक तथा लॉगआउट विन्यास कॉन्फ़िगर करें
|
||||
Comment[hne]=सत्र प्रबंधक अउ लागआउट सेटिंग कान्फिगर करव
|
||||
Comment[hr]=Konfiguriranje upravitelja sesijama i postavkama odjavljivanja
|
||||
Comment[hsb]=Rjadowar posedźenjow a nastajenjow za wotzjewjenje připrawić
|
||||
Comment[hu]=A KDE munkafolyamat és a kijelentkezési mód beállításai
|
||||
Comment[ia]=Configura le gerente de session e preferentias de exito (logout)
|
||||
Comment[id]=Atur manajer sesi dan pengaturan log keluar
|
||||
Comment[is]=Stilla setustjóra og aðgerðir við útstimplun
|
||||
Comment[ka]=სეანსების მენეჯერის და სისტემიდან გამოსვლის კონფიგურაცია
|
||||
Comment[kk]=Сеанс менеджерді және жүйеден шығу параметрлерін баптау
|
||||
Comment[km]=កំណត់រចនាសម្ព័ន្ធកម្មវិធីគ្រប់គ្រងសម័យ និងកំណត់ការចេញ
|
||||
Comment[kn]=ಅಧಿವೇಶನ (ಸೆಶನ್) ವ್ಯವಸ್ಥಾಪಕ ಹಾಗೂ ನಿರ್ಗಮನ (ಲಾಗೌಟ್) ಸಂಯೋಜನೆಗಳನ್ನು ಸಂರಚಿಸು
|
||||
Comment[ko]=세션 관리자와 로그아웃 설정 관리
|
||||
Comment[lt]=Čia galite konfigūruoti sesijos tvarkytuvę ir išsiregistravimo nustatymus
|
||||
Comment[lv]=Šeit jūs varat konfigurēt sesiju pārvaldnieku un pieslēgšanās parametrus
|
||||
Comment[mai]=सत्र प्रबंधक आओर लागआउट सेटिंग बिन्यस्त करू
|
||||
Comment[mk]=Конфигурирајте го менаџерот на сесии и поставувањата за одјавување
|
||||
Comment[ml]=സെഷനുകളുടെ നടത്തിപ്പുകാരനെയും പുറത്തിറങ്ങുന്നതിനുള്ള സജ്ജീകരണങ്ങളും ക്രമീകരിയ്ക്കുക
|
||||
Comment[mr]=सत्र व्यवस्थापक व बाहेर पडण्याची संयोजना संयोजीत करा
|
||||
Comment[ms]=Konfigur seting pengurus sesi dan bentangan
|
||||
Comment[nb]=Tilpass øktbehandleren og utlogginga
|
||||
Comment[nds]=Dat Afmellen un den Törnpleger instellen
|
||||
Comment[ne]=सत्र प्रबन्धक र लगआउट सेटिङ कन्फिगर गर्नुहोस्
|
||||
Comment[nl]=Hier kunt u het sessiebeheer en de afmeld-instellingen bepalen
|
||||
Comment[nn]=Oppsett av økthandsamar og utlogging
|
||||
Comment[pa]=ਸ਼ੈਸ਼ਨ ਮੈਨੇਜਰ ਅਤੇ ਲਾਗਆਉਟ ਸੈਟਿੰਗ ਦੀ ਸੰਰਚਨਾ
|
||||
Comment[pl]=Ustawienia sesji i wylogowania
|
||||
Comment[pt]=Configuração do gestor de sessões e das opções de encerramento
|
||||
Comment[pt_BR]=Configura o gerenciador de sessões e as opções de encerramento
|
||||
Comment[ro]=Configurează managerul de sesiune și setările de ieșire
|
||||
Comment[ru]=Настройка диспетчера сеансов
|
||||
Comment[se]=Heivet bargovuorrogieđahalli ja olggosčáliheami
|
||||
Comment[si]=වාර කළමණාකරු හා පිටවීම් සැකසුම් වෙනස් කරන්න
|
||||
Comment[sk]=Nastavenie správcu sedení a odhlásenia
|
||||
Comment[sl]=Nastavi upravljalnik sej in nastavitve odjav
|
||||
Comment[sr]=Поставке менаџера сесија и одјављивања
|
||||
Comment[sr@ijekavian]=Поставке менаџера сесија и одјављивања
|
||||
Comment[sr@ijekavianlatin]=Postavke menadžera sesija i odjavljivanja
|
||||
Comment[sr@latin]=Postavke menadžera sesija i odjavljivanja
|
||||
Comment[sv]=Anpassa sessionshanteraren och utloggningsinställningar
|
||||
Comment[ta]=அமர்வு மேளாலர் மற்றும் வெளிச்செல் அமைப்புகளை வடிவமை
|
||||
Comment[te]=సెషన్ నిర్వాహకిని మరియు లాగ్అవుట్ అమర్పులను ఆకృతీకరించుము
|
||||
Comment[tg]=Танзимоти мудири сассияҳо ва хуруҷкунӣ
|
||||
Comment[th]=ปรับแต่งการจัดการวาระงานและตั้งค่าการออกจากระบบ
|
||||
Comment[tr]=Oturum yöneticisi ve çıkış ayarlarını yapılandır
|
||||
Comment[ug]=ئەڭگىمە باشقۇرغۇچ ۋە چىقىش تەڭشىكىنى سەپلەيدۇ
|
||||
Comment[uk]=Налаштування керування сеансами та параметрів виходу з системи
|
||||
Comment[uz]=Seans boshqaruvchisini va chiqish moslamalarini moslash
|
||||
Comment[uz@cyrillic]=Сеанс бошқарувчисини ва чиқиш мосламаларини мослаш
|
||||
Comment[vi]=Cấu hình trình quản lý phiên chạy và thiết lập đăng xuất
|
||||
Comment[wa]=Apontiaedje do manaedjeu di sessions eyet apontiaedjes do dislodjaedje
|
||||
Comment[xh]=Qwalasela umphathi wesiqendu nezicwangciso zokuphuma ngaphandle
|
||||
Comment[x-test]=xxConfigure the session manager and logout settingsxx
|
||||
Comment[zh_CN]=配置会话管理器和注销设置
|
||||
Comment[zh_TW]=設定工作階段管理程式與登出設定值
|
||||
|
||||
X-KDE-Keywords=ksmserver,session,logout,confirmation,save,restore
|
||||
X-KDE-Keywords[bs]=ksmserver,sesija,odjava,potvrda,snimanje,restore
|
||||
X-KDE-Keywords[ca]=ksmserver,sessió,sortida,confirmació,desa,restaura
|
||||
X-KDE-Keywords[ca@valencia]=ksmserver,sessió,eixida,confirmació,guarda,restaura
|
||||
X-KDE-Keywords[da]=ksmserver,session,log ud,bekræftelse,gem,genskab
|
||||
X-KDE-Keywords[de]=Ksmserver,Sitzung,Abmelden,Logout,Bestätigung,Speichern,Wiederherstellen
|
||||
X-KDE-Keywords[el]=ksmserver,συνεδρία,έξοδος,επιβεβαίωση,αποθήκευση,επαναφορά
|
||||
X-KDE-Keywords[en_GB]=ksmserver,session,logout,confirmation,save,restore
|
||||
X-KDE-Keywords[es]=ksmserver,sesión,cierre de sesión,confirmación,guardado,restauración
|
||||
X-KDE-Keywords[et]=ksmserver,seanss,väljalogimine,kinnitus,salvestamine,taastamine
|
||||
X-KDE-Keywords[eu]=ksmserver,saioa,saio-bukaera,berretsi,gorde,leheneratu
|
||||
X-KDE-Keywords[fi]=ksmserver,istunto,uloskirjautuminen,kirjaudu,ulos,varmistus,varmista,tallennus,tallentaminen,tallenna,palautus,palautuminen,palauta
|
||||
X-KDE-Keywords[fr]=ksmserver, session, déconnexion, confirmation, enregistrer, restaurer
|
||||
X-KDE-Keywords[ga]=ksmserver,seisiún,logáil amach,dearbhú,sábháil,athchóiriú
|
||||
X-KDE-Keywords[gl]=ksmserver,sesión,saír,confirmación,gardar,restaurar
|
||||
X-KDE-Keywords[hu]=ksmserver,munkamenet,kijelentkezés,megerősítés,mentés,visszaállítás
|
||||
X-KDE-Keywords[ia]=ksmserver,session,claude session,confirmation,salveguarda,restabili
|
||||
X-KDE-Keywords[it]=ksmserver,sessione,uscita,conferma,salva,ripristina
|
||||
X-KDE-Keywords[kk]=ksmserver,session,logout,confirmation,save,restore
|
||||
X-KDE-Keywords[km]=ksmserver,session,logout,confirmation,save,restore
|
||||
X-KDE-Keywords[ko]=ksmserver,session,logout,confirmation,save,restore,세션,로그아웃,확인,저장,복원
|
||||
X-KDE-Keywords[mr]=ksmसर्व्हर, सत्र, लॉगआउट, कन्फरमेशन, साठवा, रिस्टोअर
|
||||
X-KDE-Keywords[nb]=ksmserver,økt,logg ut,bekreft,lagre,tilbakestill
|
||||
X-KDE-Keywords[nds]=KSM-Server,Törn,Afmellen,Nafragen,Sekern,Wedderherstellen
|
||||
X-KDE-Keywords[nl]=ksmserver,sessie,afmelden,bevestiging,opslaan,herstellen
|
||||
X-KDE-Keywords[pl]=ksmserver,sesja,wylogowanie,potwierdzenie,zapis,przywracanie
|
||||
X-KDE-Keywords[pt]=ksmserver,sessão,encerrar,confirmação,gravar,repor
|
||||
X-KDE-Keywords[pt_BR]=ksmserver,sessão,encerrar,confirmação,salvar,restaurar
|
||||
X-KDE-Keywords[ro]=ksmserver,sesiune,logout,confirmare,salvare,restabilire,ieșire
|
||||
X-KDE-Keywords[ru]=ksmserver,session,logout,confirmation,save,restore,сессия,выход,выход из системы,подтверждение,сохранить,восстановить
|
||||
X-KDE-Keywords[sk]=ksmserver,sedenie,odhlásenie,potvrdenie,uložiť,obnoviť
|
||||
X-KDE-Keywords[sl]=ksmserver,seja,seje,odjava,prijava,izklop,zaustavitev,potrditev,shranjevanje,obnavljanje
|
||||
X-KDE-Keywords[sr]=ksmserver;session;logout;confirmation;save;restore;КСМ‑сервер;сесија;одјављивање;потврда;сачувати;обновити;
|
||||
X-KDE-Keywords[sr@ijekavian]=ksmserver;session;logout;confirmation;save;restore;КСМ‑сервер;сесија;одјављивање;потврда;сачувати;обновити;
|
||||
X-KDE-Keywords[sr@ijekavianlatin]=ksmserver;session;logout;confirmation;save;restore;KSMServer;sesija;odjavljivanje;potvrda;sačuvati;obnoviti;
|
||||
X-KDE-Keywords[sr@latin]=ksmserver;session;logout;confirmation;save;restore;KSMServer;sesija;odjavljivanje;potvrda;sačuvati;obnoviti;
|
||||
X-KDE-Keywords[sv]=ksmserver,session,utloggning,bekräftelse,spara,återställ
|
||||
X-KDE-Keywords[tr]=ksmserver,oturum,çıkış,doğrulama,onaylama,kaydet,yeniden yükle
|
||||
X-KDE-Keywords[uk]=ksmserver,session,logout,confirmation,save,restore,сеанс,вихід,підтвердження,зберегти,збереження,відновити,відновлення
|
||||
X-KDE-Keywords[x-test]=xxksmserver,session,logout,confirmation,save,restorexx
|
||||
X-KDE-Keywords[zh_CN]=ksmserver,session,logout,confirmation,save,restore,会话,注销,确认,保存,还原
|
||||
X-KDE-Keywords[zh_TW]=ksmserver,session,logout,confirmation,save,restore
|
||||
|
||||
Categories=Qt;KDE;X-KDE-settings-components;
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* kcmsmserver.h
|
||||
* Copyright (c) 2000 Oswald Buddenhagen <ob6@inf.tu-dresden.de>
|
||||
*
|
||||
* based on kcmtaskbar.h
|
||||
* Copyright (c) 2000 Kurt Granroth <granroth@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
*/
|
||||
#ifndef __kcmsmserver_h__
|
||||
#define __kcmsmserver_h__
|
||||
|
||||
#include <kcmodule.h>
|
||||
|
||||
class SMServerConfigImpl;
|
||||
|
||||
|
||||
class SMServerConfig : public KCModule
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SMServerConfig( QWidget *parent=0, const QVariantList &list=QVariantList() );
|
||||
|
||||
void load();
|
||||
void save();
|
||||
void defaults();
|
||||
|
||||
private:
|
||||
SMServerConfigImpl* dialog;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,170 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SMServerConfigDlg</class>
|
||||
<widget class="QWidget" name="SMServerConfigDlg">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>477</width>
|
||||
<height>398</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="topBox">
|
||||
<property name="title">
|
||||
<string>General</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="confirmLogoutCheck">
|
||||
<property name="whatsThis">
|
||||
<string>Check this option if you want the session manager to display a logout confirmation dialog box.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Conf&irm logout</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="offerShutdownCheck">
|
||||
<property name="text">
|
||||
<string>O&ffer shutdown options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="sdGroup">
|
||||
<property name="whatsThis">
|
||||
<string>Here you can choose what should happen by default when you log out. This only has meaning, if you logged in through KDM.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Default Leave Option</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="logoutRadio">
|
||||
<property name="text">
|
||||
<string>&End current session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="haltRadio">
|
||||
<property name="text">
|
||||
<string>&Turn off computer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rebootRadio">
|
||||
<property name="text">
|
||||
<string>&Restart computer</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="loginGroup">
|
||||
<property name="whatsThis">
|
||||
<string><ul>
|
||||
<li><b>Restore previous session:</b> Will save all applications running on exit and restore them when they next start up</li>
|
||||
<li><b>Restore manually saved session: </b> Allows the session to be saved at any time via "Save Session" in the K-Menu. This means the currently started applications will reappear when they next start up.</li>
|
||||
<li><b>Start with an empty session:</b> Do not save anything. Will come up with an empty desktop on next start.</li>
|
||||
</ul></string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>On Login</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="previousSessionRadio">
|
||||
<property name="text">
|
||||
<string>Restore &previous session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="savedSessionRadio">
|
||||
<property name="text">
|
||||
<string>Restore &manually saved session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="emptySessionRadio">
|
||||
<property name="text">
|
||||
<string>Start with an empty &session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="textLabel1">
|
||||
<property name="text">
|
||||
<string>Applications to be e&xcluded from sessions:</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>excludeLineedit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="KLineEdit" name="excludeLineedit">
|
||||
<property name="whatsThis">
|
||||
<string>Here you can enter a colon or comma separated list of applications that should not be saved in sessions, and therefore will not be started when restoring a session. For example 'xterm:konsole' or 'xterm,konsole'.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>klineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>offerShutdownCheck</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>sdGroup</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -1,39 +0,0 @@
|
|||
/***************************************************************************
|
||||
smserverconfigimpl.cpp - description
|
||||
-------------------
|
||||
begin : Thu May 17 2001
|
||||
copyright : (C) 2001 by stulle
|
||||
email : stulle@tux
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "smserverconfigimpl.h"
|
||||
#include "moc_smserverconfigimpl.cpp"
|
||||
|
||||
SMServerConfigImpl::SMServerConfigImpl(QWidget *parent ) : SMServerConfigDlg(parent) {
|
||||
connect(confirmLogoutCheck,SIGNAL(toggled(bool)), SLOT(configChanged()));
|
||||
connect(previousSessionRadio,SIGNAL(toggled(bool)), SLOT(configChanged()));
|
||||
connect(savedSessionRadio,SIGNAL(toggled(bool)), SLOT(configChanged()));
|
||||
connect(emptySessionRadio,SIGNAL(toggled(bool)), SLOT(configChanged()));
|
||||
connect(logoutRadio,SIGNAL(toggled(bool)), SLOT(configChanged()));
|
||||
connect(haltRadio,SIGNAL(toggled(bool)), SLOT(configChanged()));
|
||||
connect(rebootRadio,SIGNAL(toggled(bool)), SLOT(configChanged()));
|
||||
connect(excludeLineedit,SIGNAL(textChanged(QString)),SLOT(configChanged()));
|
||||
connect(offerShutdownCheck,SIGNAL(toggled(bool)),SLOT(configChanged()));
|
||||
}
|
||||
SMServerConfigImpl::~SMServerConfigImpl(){
|
||||
}
|
||||
/** No descriptions */
|
||||
void SMServerConfigImpl::configChanged(){
|
||||
|
||||
emit changed();
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/***************************************************************************
|
||||
smserverconfigimpl.h - description
|
||||
-------------------
|
||||
begin : Thu May 17 2001
|
||||
copyright : (C) 2001 by stulle
|
||||
email : stulle@tux
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SMSERVERCONFIGIMPL_H
|
||||
#define SMSERVERCONFIGIMPL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "ui_smserverconfigdlg.h"
|
||||
|
||||
/**
|
||||
*@author stulle
|
||||
*/
|
||||
|
||||
class SMServerConfigDlg : public QWidget, public Ui::SMServerConfigDlg
|
||||
{
|
||||
public:
|
||||
SMServerConfigDlg( QWidget *parent ) : QWidget( parent ) {
|
||||
setupUi( this );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SMServerConfigImpl : public SMServerConfigDlg {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SMServerConfigImpl(QWidget *parent=0);
|
||||
~SMServerConfigImpl();
|
||||
public Q_SLOTS: // Public slots
|
||||
/** No descriptions */
|
||||
void configChanged();
|
||||
Q_SIGNALS: // Signals
|
||||
/** No descriptions */
|
||||
void changed();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,253 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "config-ksmserver.h"
|
||||
#include "server.h"
|
||||
|
||||
#include <fixx11h.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <KMessageBox>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kcmdlineargs.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <kaboutdata.h>
|
||||
#include <kdebug.h>
|
||||
#include <klocale.h>
|
||||
#include <kglobal.h>
|
||||
#include <kconfig.h>
|
||||
#include <kwindowsystem.h>
|
||||
#include <kcrash.h>
|
||||
#include <QtGui/qx11info_x11.h>
|
||||
#include <QtCore/qfile.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
static const char version[] = "0.4";
|
||||
static const char description[] = I18N_NOOP( "The reliable KDE session manager that talks the standard X11R6 \nsession management protocol (XSMP)." );
|
||||
|
||||
extern KSMServer* the_server;
|
||||
|
||||
void IoErrorHandler ( IceConn iceConn)
|
||||
{
|
||||
the_server->ioError( iceConn );
|
||||
}
|
||||
|
||||
bool writeTest(QByteArray path)
|
||||
{
|
||||
path += "/XXXXXX";
|
||||
int fd = mkstemp(path.data());
|
||||
if (fd == -1)
|
||||
return false;
|
||||
if (write(fd, "Hello World\n", 12) == -1)
|
||||
{
|
||||
int save_errno = errno;
|
||||
close(fd);
|
||||
unlink(path.data());
|
||||
errno = save_errno;
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
unlink(path.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
void sanity_check( int argc, char* argv[], KAboutData* aboutDataPtr )
|
||||
{
|
||||
QString msg;
|
||||
QByteArray path = getenv("HOME");
|
||||
QByteArray readOnly = getenv("KDE_HOME_READONLY");
|
||||
if (path.isEmpty())
|
||||
{
|
||||
msg = QLatin1String("$HOME not set!");
|
||||
}
|
||||
if (msg.isEmpty() && access(path.data(), W_OK))
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
msg = QLatin1String("$HOME directory (%1) does not exist.");
|
||||
else if (readOnly.isEmpty())
|
||||
msg = QLatin1String("No write access to $HOME directory (%1).");
|
||||
}
|
||||
if (msg.isEmpty() && access(path.data(), R_OK))
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
msg = "$HOME directory (%1) does not exist.";
|
||||
else
|
||||
msg = "No read access to $HOME directory (%1).";
|
||||
}
|
||||
if (msg.isEmpty() && readOnly.isEmpty() && !writeTest(path))
|
||||
{
|
||||
if (errno == ENOSPC)
|
||||
msg = "$HOME directory (%1) is out of disk space.";
|
||||
else
|
||||
msg = QByteArray("Writing to the $HOME directory (%1) failed with\n "
|
||||
"the error '")+QByteArray(strerror(errno))+QByteArray("'");
|
||||
}
|
||||
if (msg.isEmpty())
|
||||
{
|
||||
path = getenv("ICEAUTHORITY");
|
||||
if (path.isEmpty())
|
||||
{
|
||||
path = getenv("HOME");
|
||||
path += "/.ICEauthority";
|
||||
}
|
||||
|
||||
if (access(path.data(), W_OK) && (errno != ENOENT))
|
||||
msg = "No write access to '%1'.";
|
||||
else if (access(path.data(), R_OK) && (errno != ENOENT))
|
||||
msg = "No read access to '%1'.";
|
||||
}
|
||||
if (msg.isEmpty())
|
||||
{
|
||||
path = getenv("TMPDIR");
|
||||
if (path.isEmpty())
|
||||
path = "/tmp";
|
||||
if (!writeTest(path))
|
||||
{
|
||||
if (errno == ENOSPC)
|
||||
msg = "Temp directory (%1) is out of disk space.";
|
||||
else
|
||||
msg = "Writing to the temp directory (%1) failed with\n "
|
||||
"the error '"+QByteArray(strerror(errno))+QByteArray("'");
|
||||
}
|
||||
}
|
||||
if (msg.isEmpty() && (path != "/tmp"))
|
||||
{
|
||||
path = "/tmp";
|
||||
if (!writeTest(path))
|
||||
{
|
||||
if (errno == ENOSPC)
|
||||
msg = "Temp directory (%1) is out of disk space.";
|
||||
else
|
||||
msg = "Writing to the temp directory (%1) failed with\n "
|
||||
"the error '"+QByteArray(strerror(errno))+QByteArray("'");
|
||||
}
|
||||
}
|
||||
if (msg.isEmpty())
|
||||
{
|
||||
path += "/.ICE-unix";
|
||||
if (access(path.data(), W_OK) && (errno != ENOENT))
|
||||
msg = "No write access to '%1'.";
|
||||
else if (access(path.data(), R_OK) && (errno != ENOENT))
|
||||
msg = "No read access to '%1'.";
|
||||
}
|
||||
if (!msg.isEmpty())
|
||||
{
|
||||
const char *msg_pre =
|
||||
"The following installation problem was detected\n"
|
||||
"while trying to start KDE:"
|
||||
"\n\n ";
|
||||
const char *msg_post = "\n\nKDE is unable to start.\n";
|
||||
fputs(msg_pre, stderr);
|
||||
fprintf(stderr, "%s", qPrintable(msg.arg(QFile::decodeName(path))));
|
||||
fputs(msg_post, stderr);
|
||||
|
||||
QApplication a(argc, argv);
|
||||
KComponentData i(aboutDataPtr);
|
||||
QString qmsg = msg_pre+msg.arg(QFile::decodeName(path))+msg_post;
|
||||
KMessageBox::error(0, qmsg, "KDE Installation Problem!");
|
||||
exit(255);
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
KAboutData aboutData( "ksmserver", 0, ki18n("The KDE Session Manager"),
|
||||
version, ki18n(description), KAboutData::License_BSD,
|
||||
ki18n("(C) 2000, The KDE Developers"));
|
||||
aboutData.addAuthor(ki18n("Matthias Ettrich"),KLocalizedString(), "ettrich@kde.org");
|
||||
aboutData.addAuthor(ki18n("Luboš Luňák"), ki18n( "Maintainer" ), "l.lunak@kde.org" );
|
||||
|
||||
sanity_check(argc, argv, &aboutData);
|
||||
|
||||
KCmdLineArgs::init(argc, argv, &aboutData);
|
||||
|
||||
KCmdLineOptions options;
|
||||
options.add("r");
|
||||
options.add("restore", ki18n("Restores the saved user session if available"));
|
||||
options.add("w");
|
||||
options.add("windowmanager <wm>", ki18n("Starts 'wm' in case no other window manager is \nparticipating in the session. Default is 'kwin'"));
|
||||
options.add("nolocal", ki18n("Also allow remote connections"));
|
||||
KCmdLineArgs::addCmdLineOptions( options );
|
||||
|
||||
::unsetenv("SESSION_MANAGER");
|
||||
KApplication app;
|
||||
fcntl(ConnectionNumber(QX11Info::display()), F_SETFD, 1);
|
||||
|
||||
app.setQuitOnLastWindowClosed(false); // #169486
|
||||
|
||||
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
||||
|
||||
if( !QDBusConnection::sessionBus().interface()->registerService( "org.kde.ksmserver", QDBusConnectionInterface::DontQueueService ) )
|
||||
{
|
||||
qWarning("Could not register with D-BUS. Aborting.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
QString wm = args->getOption("windowmanager");
|
||||
|
||||
bool only_local = args->isSet("local");
|
||||
#ifndef HAVE__ICETRANSNOLISTEN
|
||||
/* this seems strange, but the default is only_local, so if !only_local
|
||||
* the option --nolocal was given, and we warn (the option --nolocal
|
||||
* does nothing on this platform, as here the default is reversed)
|
||||
*/
|
||||
if (!only_local) {
|
||||
qWarning("--[no]local is not supported on your platform. Sorry.");
|
||||
}
|
||||
only_local = false;
|
||||
#endif
|
||||
|
||||
KSMServer *server = new KSMServer( wm, only_local );
|
||||
|
||||
KCrash::setFlags(KCrash::Log);
|
||||
|
||||
IceSetIOErrorHandler( IoErrorHandler );
|
||||
|
||||
KConfigGroup config(KGlobal::config(), "General");
|
||||
|
||||
int realScreenCount = ScreenCount( QX11Info::display() );
|
||||
bool screenCountChanged =
|
||||
( config.readEntry( "screenCount", realScreenCount ) != realScreenCount );
|
||||
|
||||
QString loginMode = config.readEntry( "loginMode", "restorePreviousLogout" );
|
||||
|
||||
if ( args->isSet("restore") && ! screenCountChanged )
|
||||
server->restoreSession( SESSION_BY_USER );
|
||||
else if ( loginMode == "default" || screenCountChanged )
|
||||
server->startDefaultSession();
|
||||
else if ( loginMode == "restorePreviousLogout" )
|
||||
server->restoreSession( SESSION_PREVIOUS_LOGOUT );
|
||||
else if ( loginMode == "restoreSavedSession" )
|
||||
server->restoreSession( SESSION_BY_USER );
|
||||
else
|
||||
server->startDefaultSession();
|
||||
return app.exec();
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<!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.KSMServerInterface">
|
||||
<method name="logout">
|
||||
<arg type="i" direction="in"/>
|
||||
<arg type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="canShutdown">
|
||||
<arg type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="sessionList">
|
||||
<arg type="as" direction="out"/>
|
||||
</method>
|
||||
<method name="currentSession">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="saveCurrentSession">
|
||||
</method>
|
||||
<method name="saveCurrentSessionAs">
|
||||
<arg type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="suspendStartup">
|
||||
<arg type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="resumeStartup">
|
||||
<arg type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="wmChanged"/>
|
||||
<method name="saveSubSession">
|
||||
<arg type="s" direction="in"/>
|
||||
<arg type="as" direction="in"/>
|
||||
<arg type="as" direction="in"/>
|
||||
</method>
|
||||
<method name="restoreSubSession">
|
||||
<arg type="s" direction="in"/>
|
||||
</method>
|
||||
<signal name="subSessionClosed"/>
|
||||
<signal name="subSessionCloseCanceled"/>
|
||||
<signal name="subSessionOpened"/>
|
||||
</interface>
|
||||
</node>
|
1041
ksmserver/server.cpp
1041
ksmserver/server.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,243 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QDBusInterface>
|
||||
#include <QMap>
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kworkspace/kworkspace.h>
|
||||
#include <kmessagebox.h>
|
||||
|
||||
#define INT32 QINT32
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include <X11/ICE/ICElib.h>
|
||||
extern "C" {
|
||||
#include <X11/ICE/ICEutil.h>
|
||||
#include <X11/ICE/ICEmsg.h>
|
||||
#include <X11/ICE/ICEproto.h>
|
||||
#include <X11/SM/SM.h>
|
||||
#include <X11/SM/SMlib.h>
|
||||
}
|
||||
|
||||
#include <fixx11h.h>
|
||||
|
||||
#define SESSION_PREVIOUS_LOGOUT "saved at previous logout"
|
||||
#define SESSION_BY_USER "saved by user"
|
||||
|
||||
class KSMListener;
|
||||
class KSMConnection;
|
||||
class KSMClient;
|
||||
|
||||
class KSMServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KSMServer( const QString& windowManager, bool only_local );
|
||||
~KSMServer();
|
||||
|
||||
static KSMServer* self();
|
||||
|
||||
void* watchConnection( IceConn iceConn );
|
||||
void removeConnection( KSMConnection* conn );
|
||||
|
||||
KSMClient* newClient( SmsConn );
|
||||
void deleteClient( KSMClient* client );
|
||||
|
||||
// callbacks
|
||||
void saveYourselfDone( KSMClient* client, bool success );
|
||||
void interactRequest( KSMClient* client, int dialogType );
|
||||
void interactDone( KSMClient* client, bool cancelShutdown );
|
||||
void phase2Request( KSMClient* client );
|
||||
|
||||
// error handling
|
||||
void ioError( IceConn iceConn );
|
||||
|
||||
// notification
|
||||
void clientSetProgram( KSMClient* client );
|
||||
void clientRegistered( const char* previousId );
|
||||
|
||||
// public API
|
||||
void restoreSession( const QString &sessionName );
|
||||
void startDefaultSession();
|
||||
void shutdown( KWorkSpace::ShutdownConfirm confirm,
|
||||
KWorkSpace::ShutdownType sdtype );
|
||||
|
||||
virtual void suspendStartup( const QString &app );
|
||||
virtual void resumeStartup( const QString &app );
|
||||
|
||||
void launchWM( const QList< QStringList >& wmStartCommands );
|
||||
|
||||
public Q_SLOTS:
|
||||
void cleanUp();
|
||||
|
||||
private Q_SLOTS:
|
||||
void newConnection( int socket );
|
||||
void processData( int socket );
|
||||
|
||||
void protectionTimeout();
|
||||
void timeoutQuit();
|
||||
void timeoutWMQuit();
|
||||
void kcmPhase1Timeout();
|
||||
void kcmPhase2Timeout();
|
||||
void pendingShutdownTimeout();
|
||||
void logoutSoundTimeout();
|
||||
|
||||
void autoStart0();
|
||||
void autoStart1();
|
||||
void autoStart2();
|
||||
void tryRestoreNext();
|
||||
void startupSuspendTimeout();
|
||||
void wmProcessChange();
|
||||
void logoutSoundFinished();
|
||||
void autoStart0Done();
|
||||
void autoStart1Done();
|
||||
void autoStart2Done();
|
||||
void kcmPhase1Done();
|
||||
void kcmPhase2Done();
|
||||
|
||||
void defaultLogout();
|
||||
void logoutWithoutConfirmation();
|
||||
void haltWithoutConfirmation();
|
||||
void rebootWithoutConfirmation();
|
||||
|
||||
private:
|
||||
void handlePendingInteractions();
|
||||
void completeShutdownOrCheckpoint();
|
||||
void startKilling();
|
||||
void startKillingSubSession();
|
||||
void performStandardKilling();
|
||||
void completeKilling();
|
||||
void completeKillingSubSession();
|
||||
void killWM();
|
||||
void signalSubSessionClosed();
|
||||
void completeKillingWM();
|
||||
void cancelShutdown( KSMClient* c );
|
||||
void killingCompleted();
|
||||
void createLogoutEffectWidget();
|
||||
|
||||
void discardSession();
|
||||
void storeSession();
|
||||
|
||||
void startProtection();
|
||||
void endProtection();
|
||||
|
||||
bool startApplication( const QStringList& command,
|
||||
const QString& clientMachine = QString(),
|
||||
const QString& userId = QString());
|
||||
void executeCommand( const QStringList& command );
|
||||
|
||||
bool isWM( const KSMClient* client ) const;
|
||||
bool isWM( const QString& command ) const;
|
||||
void selectWm( const QString& kdewm );
|
||||
bool defaultSession() const; // empty session
|
||||
void setupXIOErrorHandler();
|
||||
|
||||
bool checkStartupSuspend();
|
||||
void finishStartup();
|
||||
void resumeStartupInternal();
|
||||
void setupShortcuts();
|
||||
|
||||
// public dcop interface
|
||||
|
||||
public Q_SLOTS: //public dcop interface
|
||||
void logout( int, int );
|
||||
bool canShutdown();
|
||||
QString currentSession();
|
||||
void saveCurrentSession();
|
||||
void saveCurrentSessionAs( const QString & );
|
||||
QStringList sessionList();
|
||||
void wmChanged();
|
||||
void saveSubSession( const QString &name, QStringList saveAndClose,
|
||||
QStringList saveOnly = QStringList() );
|
||||
void restoreSubSession( const QString &name );
|
||||
|
||||
Q_SIGNALS:
|
||||
void subSessionClosed();
|
||||
void subSessionCloseCanceled();
|
||||
void subSessionOpened();
|
||||
|
||||
private:
|
||||
QList<KSMListener*> listener;
|
||||
QList<KSMClient*> clients;
|
||||
|
||||
enum State {
|
||||
Idle,
|
||||
LaunchingWM, AutoStart0, KcmInitPhase1, AutoStart1, Restoring, FinishingStartup, // startup
|
||||
Shutdown, Checkpoint, Killing, KillingWM, WaitingForKNotify, // shutdown
|
||||
ClosingSubSession, KillingSubSession, RestoringSubSession
|
||||
};
|
||||
State state;
|
||||
bool dialogActive;
|
||||
bool saveSession;
|
||||
int wmPhase1WaitingCount;
|
||||
int saveType;
|
||||
QMap< QString, int > startupSuspendCount;
|
||||
|
||||
KWorkSpace::ShutdownType shutdownType;
|
||||
|
||||
bool clean;
|
||||
KSMClient* clientInteracting;
|
||||
QString wm;
|
||||
QStringList wmCommands;
|
||||
QProcess* wmProcess;
|
||||
QString sessionGroup;
|
||||
QString sessionName;
|
||||
QTimer protectionTimer;
|
||||
QTimer restoreTimer;
|
||||
QString xonCommand;
|
||||
QTimer startupSuspendTimeoutTimer;
|
||||
bool waitAutoStart2;
|
||||
bool waitKcmInit2;
|
||||
QTimer pendingShutdown;
|
||||
QWidget* logoutEffectWidget;
|
||||
KWorkSpace::ShutdownConfirm pendingShutdown_confirm;
|
||||
KWorkSpace::ShutdownType pendingShutdown_sdtype;
|
||||
|
||||
// sequential startup
|
||||
int appsToStart;
|
||||
int lastAppStarted;
|
||||
QString lastIdStarted;
|
||||
|
||||
QStringList excludeApps;
|
||||
|
||||
QDBusInterface* klauncherSignals;
|
||||
QDBusInterface* kcminitSignals;
|
||||
|
||||
uint inhibitCookie;
|
||||
|
||||
//subSession stuff
|
||||
QList<KSMClient*> clientsToKill;
|
||||
QList<KSMClient*> clientsToSave;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,670 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
|
||||
relatively small extensions by Oswald Buddenhagen <ob6@inf.tu-dresden.de>
|
||||
|
||||
some code taken from the dcopserver (part of the KDE libraries), which is
|
||||
Copyright 1999 Matthias Ettrich <ettrich@kde.org>
|
||||
Copyright 1999 Preston Brown <pbrown@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include <config-unix.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include <KApplication>
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KGlobal>
|
||||
#include <KLocale>
|
||||
#include <KNotification>
|
||||
#include <KStandardDirs>
|
||||
#include <KTemporaryFile>
|
||||
#include <kworkspace/kdisplaymanager.h>
|
||||
|
||||
#include "server.h"
|
||||
#include "global.h"
|
||||
#include "client.h"
|
||||
#include "shutdowndlg.h"
|
||||
|
||||
#include <solid/powermanagement.h>
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <QDesktopWidget>
|
||||
#include <QtGui/qx11info_x11.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
void KSMServer::logout( int confirm, int sdtype )
|
||||
{
|
||||
shutdown( (KWorkSpace::ShutdownConfirm)confirm,
|
||||
(KWorkSpace::ShutdownType)sdtype);
|
||||
}
|
||||
|
||||
bool KSMServer::canShutdown()
|
||||
{
|
||||
KSharedConfig::Ptr config = KGlobal::config();
|
||||
config->reparseConfiguration(); // config may have changed in the KControl module
|
||||
KConfigGroup cg( config, "General");
|
||||
|
||||
return cg.readEntry( "offerShutdown", true ) && KDisplayManager().canShutdown();
|
||||
}
|
||||
|
||||
void KSMServer::shutdown( KWorkSpace::ShutdownConfirm confirm,
|
||||
KWorkSpace::ShutdownType sdtype )
|
||||
{
|
||||
pendingShutdown.stop();
|
||||
if( dialogActive )
|
||||
return;
|
||||
if( state >= Shutdown ) // already performing shutdown
|
||||
return;
|
||||
if( state != Idle ) // performing startup
|
||||
{
|
||||
// perform shutdown as soon as startup is finished, in order to avoid saving partial session
|
||||
if( !pendingShutdown.isActive())
|
||||
{
|
||||
pendingShutdown.start( 1000 );
|
||||
pendingShutdown_confirm = confirm;
|
||||
pendingShutdown_sdtype = sdtype;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
KSharedConfig::Ptr config = KGlobal::config();
|
||||
config->reparseConfiguration(); // config may have changed in the KControl module
|
||||
|
||||
KConfigGroup cg( config, "General");
|
||||
|
||||
bool logoutConfirmed =
|
||||
(confirm == KWorkSpace::ShutdownConfirmYes) ? false :
|
||||
(confirm == KWorkSpace::ShutdownConfirmNo) ? true :
|
||||
!cg.readEntry( "confirmLogout", true );
|
||||
bool choose = false;
|
||||
bool maysd = false;
|
||||
if (cg.readEntry( "offerShutdown", true ) && KDisplayManager().canShutdown())
|
||||
maysd = true;
|
||||
if (!maysd) {
|
||||
if (sdtype != KWorkSpace::ShutdownTypeNone &&
|
||||
sdtype != KWorkSpace::ShutdownTypeDefault &&
|
||||
logoutConfirmed)
|
||||
return; /* unsupported fast shutdown */
|
||||
sdtype = KWorkSpace::ShutdownTypeNone;
|
||||
} else if (sdtype == KWorkSpace::ShutdownTypeDefault) {
|
||||
sdtype = (KWorkSpace::ShutdownType)
|
||||
cg.readEntry( "shutdownType", (int)KWorkSpace::ShutdownTypeNone );
|
||||
choose = true;
|
||||
}
|
||||
|
||||
dialogActive = true;
|
||||
if ( !logoutConfirmed ) {
|
||||
KApplication::kApplication()->updateUserTimestamp();
|
||||
logoutConfirmed = KSMShutdownDlg::confirmShutdown( maysd, choose, sdtype);
|
||||
// ###### We can't make the screen remain gray while talking to the apps,
|
||||
// because this prevents interaction ("do you want to save", etc.)
|
||||
// TODO: turn the feedback widget into a list of apps to be closed,
|
||||
// with an indicator of the current status for each.
|
||||
KSMShutdownFeedback::stop(); // make the screen become normal again
|
||||
}
|
||||
|
||||
if ( logoutConfirmed ) {
|
||||
|
||||
// If the logout was confirmed, let's start a powermanagement inhibition.
|
||||
// We store the cookie so we can interrupt it if the logout will be canceled
|
||||
inhibitCookie = Solid::PowerManagement::beginSuppressingSleep();
|
||||
|
||||
shutdownType = sdtype;
|
||||
|
||||
// shall we save the session on logout?
|
||||
saveSession = ( cg.readEntry( "loginMode", "restorePreviousLogout" ) == "restorePreviousLogout" );
|
||||
|
||||
if ( saveSession )
|
||||
sessionGroup = QString("Session: ") + SESSION_PREVIOUS_LOGOUT;
|
||||
|
||||
// Set the real desktop background to black so that exit looks
|
||||
// clean regardless of what was on "our" desktop.
|
||||
QPalette palette;
|
||||
palette.setColor( kapp->desktop()->backgroundRole(), Qt::black );
|
||||
kapp->desktop()->setPalette(palette);
|
||||
state = Shutdown;
|
||||
wmPhase1WaitingCount = 0;
|
||||
saveType = saveSession?SmSaveBoth:SmSaveGlobal;
|
||||
startProtection();
|
||||
foreach( KSMClient* c, clients ) {
|
||||
c->resetState();
|
||||
// Whoever came with the idea of phase 2 got it backwards
|
||||
// unfortunately. Window manager should be the very first
|
||||
// one saving session data, not the last one, as possible
|
||||
// user interaction during session save may alter
|
||||
// window positions etc.
|
||||
// Moreover, KWin's focus stealing prevention would lead
|
||||
// to undesired effects while session saving (dialogs
|
||||
// wouldn't be activated), so it needs be assured that
|
||||
// KWin will turn it off temporarily before any other
|
||||
// user interaction takes place.
|
||||
// Therefore, make sure the WM finishes its phase 1
|
||||
// before others a chance to change anything.
|
||||
// KWin will check if the session manager is ksmserver,
|
||||
// and if yes it will save in phase 1 instead of phase 2.
|
||||
if( isWM( c ) )
|
||||
++wmPhase1WaitingCount;
|
||||
}
|
||||
if (wmPhase1WaitingCount > 0) {
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if( isWM( c ) )
|
||||
SmsSaveYourself( c->connection(), saveType,
|
||||
true, SmInteractStyleAny, false );
|
||||
}
|
||||
} else { // no WM, simply start them all
|
||||
foreach( KSMClient* c, clients )
|
||||
SmsSaveYourself( c->connection(), saveType,
|
||||
true, SmInteractStyleAny, false );
|
||||
}
|
||||
if ( clients.isEmpty() )
|
||||
completeShutdownOrCheckpoint();
|
||||
}
|
||||
dialogActive = false;
|
||||
}
|
||||
|
||||
void KSMServer::pendingShutdownTimeout()
|
||||
{
|
||||
shutdown( pendingShutdown_confirm, pendingShutdown_sdtype );
|
||||
}
|
||||
|
||||
void KSMServer::saveCurrentSession()
|
||||
{
|
||||
if ( state != Idle || dialogActive )
|
||||
return;
|
||||
|
||||
if ( currentSession().isEmpty() || currentSession() == SESSION_PREVIOUS_LOGOUT )
|
||||
sessionGroup = QString("Session: ") + SESSION_BY_USER;
|
||||
|
||||
state = Checkpoint;
|
||||
wmPhase1WaitingCount = 0;
|
||||
saveType = SmSaveLocal;
|
||||
saveSession = true;
|
||||
foreach( KSMClient* c, clients ) {
|
||||
c->resetState();
|
||||
if( isWM( c ) )
|
||||
++wmPhase1WaitingCount;
|
||||
}
|
||||
if (wmPhase1WaitingCount > 0) {
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if( isWM( c ) )
|
||||
SmsSaveYourself( c->connection(), saveType, false, SmInteractStyleNone, false );
|
||||
}
|
||||
} else {
|
||||
foreach( KSMClient* c, clients )
|
||||
SmsSaveYourself( c->connection(), saveType, false, SmInteractStyleNone, false );
|
||||
}
|
||||
if ( clients.isEmpty() )
|
||||
completeShutdownOrCheckpoint();
|
||||
}
|
||||
|
||||
void KSMServer::saveCurrentSessionAs( const QString &session )
|
||||
{
|
||||
if ( state != Idle || dialogActive )
|
||||
return;
|
||||
sessionGroup = "Session: " + session;
|
||||
saveCurrentSession();
|
||||
}
|
||||
|
||||
// callbacks
|
||||
void KSMServer::saveYourselfDone( KSMClient* client, bool success )
|
||||
{
|
||||
if ( state == Idle ) {
|
||||
// State saving when it's not shutdown or checkpoint. Probably
|
||||
// a shutdown was canceled and the client is finished saving
|
||||
// only now. Discard the saved state in order to avoid
|
||||
// the saved data building up.
|
||||
QStringList discard = client->discardCommand();
|
||||
if( !discard.isEmpty())
|
||||
executeCommand( discard );
|
||||
return;
|
||||
}
|
||||
if ( success ) {
|
||||
client->saveYourselfDone = true;
|
||||
completeShutdownOrCheckpoint();
|
||||
} else {
|
||||
// fake success to make KDE's logout not block with broken
|
||||
// apps. A perfect ksmserver would display a warning box at
|
||||
// the very end.
|
||||
client->saveYourselfDone = true;
|
||||
completeShutdownOrCheckpoint();
|
||||
}
|
||||
startProtection();
|
||||
if( isWM( client ) && !client->wasPhase2 && wmPhase1WaitingCount > 0 ) {
|
||||
--wmPhase1WaitingCount;
|
||||
// WM finished its phase1, save the rest
|
||||
if( wmPhase1WaitingCount == 0 ) {
|
||||
foreach( KSMClient* c, clients )
|
||||
if( !isWM( c ))
|
||||
SmsSaveYourself( c->connection(), saveType, saveType != SmSaveLocal,
|
||||
saveType != SmSaveLocal ? SmInteractStyleAny : SmInteractStyleNone,
|
||||
false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::interactRequest( KSMClient* client, int /*dialogType*/ )
|
||||
{
|
||||
if ( state == Shutdown || state == ClosingSubSession )
|
||||
client->pendingInteraction = true;
|
||||
else
|
||||
SmsInteract( client->connection() );
|
||||
|
||||
handlePendingInteractions();
|
||||
}
|
||||
|
||||
void KSMServer::interactDone( KSMClient* client, bool cancelShutdown_ )
|
||||
{
|
||||
if ( client != clientInteracting )
|
||||
return; // should not happen
|
||||
clientInteracting = 0;
|
||||
if ( cancelShutdown_ )
|
||||
cancelShutdown( client );
|
||||
else
|
||||
handlePendingInteractions();
|
||||
}
|
||||
|
||||
|
||||
void KSMServer::phase2Request( KSMClient* client )
|
||||
{
|
||||
client->waitForPhase2 = true;
|
||||
client->wasPhase2 = true;
|
||||
completeShutdownOrCheckpoint();
|
||||
if( isWM( client ) && wmPhase1WaitingCount > 0 ) {
|
||||
--wmPhase1WaitingCount;
|
||||
// WM finished its phase1 and requests phase2, save the rest
|
||||
if( wmPhase1WaitingCount == 0 ) {
|
||||
foreach( KSMClient* c, clients )
|
||||
if( !isWM( c ))
|
||||
SmsSaveYourself( c->connection(), saveType, saveType != SmSaveLocal,
|
||||
saveType != SmSaveLocal ? SmInteractStyleAny : SmInteractStyleNone,
|
||||
false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::handlePendingInteractions()
|
||||
{
|
||||
if ( clientInteracting )
|
||||
return;
|
||||
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if ( c->pendingInteraction ) {
|
||||
clientInteracting = c;
|
||||
c->pendingInteraction = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( clientInteracting ) {
|
||||
endProtection();
|
||||
SmsInteract( clientInteracting->connection() );
|
||||
} else {
|
||||
startProtection();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KSMServer::cancelShutdown( KSMClient* c )
|
||||
{
|
||||
clientInteracting = 0;
|
||||
kDebug() << state;
|
||||
if ( state == ClosingSubSession ) {
|
||||
clientsToKill.clear();
|
||||
clientsToSave.clear();
|
||||
emit subSessionCloseCanceled();
|
||||
} else {
|
||||
Solid::PowerManagement::stopSuppressingSleep(inhibitCookie);
|
||||
kDebug() << "Client " << c->program() << " (" << c->clientId() << ") canceled shutdown.";
|
||||
KSMShutdownFeedback::stop(); // make the screen become normal again
|
||||
KNotification::event(
|
||||
"kde/cancellogout" , QString(),
|
||||
i18n("Logout canceled by '%1'", c->program())
|
||||
);
|
||||
foreach( KSMClient* c, clients ) {
|
||||
SmsShutdownCancelled( c->connection() );
|
||||
if( c->saveYourselfDone ) {
|
||||
// Discard also saved state.
|
||||
QStringList discard = c->discardCommand();
|
||||
if( !discard.isEmpty())
|
||||
executeCommand( discard );
|
||||
}
|
||||
}
|
||||
}
|
||||
state = Idle;
|
||||
}
|
||||
|
||||
void KSMServer::startProtection()
|
||||
{
|
||||
KSharedConfig::Ptr config = KGlobal::config();
|
||||
config->reparseConfiguration(); // config may have changed in the KControl module
|
||||
KConfigGroup cg( config, "General" );
|
||||
|
||||
int timeout = cg.readEntry( "clientShutdownTimeoutSecs", 15 ) * 1000;
|
||||
|
||||
protectionTimer.setSingleShot( true );
|
||||
protectionTimer.start( timeout );
|
||||
}
|
||||
|
||||
void KSMServer::endProtection()
|
||||
{
|
||||
protectionTimer.stop();
|
||||
}
|
||||
|
||||
/*
|
||||
Internal protection slot, invoked when clients do not react during
|
||||
shutdown.
|
||||
*/
|
||||
void KSMServer::protectionTimeout()
|
||||
{
|
||||
if ( ( state != Shutdown && state != Checkpoint && state != ClosingSubSession ) || clientInteracting )
|
||||
return;
|
||||
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if ( !c->saveYourselfDone && !c->waitForPhase2 ) {
|
||||
kDebug() << "protectionTimeout: client " << c->program() << "(" << c->clientId() << ")";
|
||||
c->saveYourselfDone = true;
|
||||
}
|
||||
}
|
||||
completeShutdownOrCheckpoint();
|
||||
startProtection();
|
||||
}
|
||||
|
||||
void KSMServer::completeShutdownOrCheckpoint()
|
||||
{
|
||||
if ( state != Shutdown && state != Checkpoint && state != ClosingSubSession )
|
||||
return;
|
||||
|
||||
QList<KSMClient*> pendingClients;
|
||||
if (state == ClosingSubSession)
|
||||
pendingClients = clientsToSave;
|
||||
else
|
||||
pendingClients = clients;
|
||||
|
||||
foreach( KSMClient* c, pendingClients ) {
|
||||
if ( !c->saveYourselfDone && !c->waitForPhase2 )
|
||||
return; // not done yet
|
||||
}
|
||||
|
||||
// do phase 2
|
||||
bool waitForPhase2 = false;
|
||||
foreach( KSMClient* c, pendingClients ) {
|
||||
if ( !c->saveYourselfDone && c->waitForPhase2 ) {
|
||||
c->waitForPhase2 = false;
|
||||
SmsSaveYourselfPhase2( c->connection() );
|
||||
waitForPhase2 = true;
|
||||
}
|
||||
}
|
||||
if ( waitForPhase2 )
|
||||
return;
|
||||
|
||||
if ( saveSession )
|
||||
storeSession();
|
||||
else
|
||||
discardSession();
|
||||
|
||||
if ( state == Shutdown ) {
|
||||
// KDE says good bye
|
||||
KNotification *n = new KNotification(this);
|
||||
n->setEventID("kde/exitkde");
|
||||
connect(n, SIGNAL(closed()) , this, SLOT(logoutSoundFinished()) );
|
||||
// https://bugs.kde.org/show_bug.cgi?id=228005
|
||||
// if sound is not working for some reason the closed() signal never happens
|
||||
// and logoutSoundFinished() never gets called. Add this timer to make
|
||||
// sure the shutdown procedure continues even if sound system is broken.
|
||||
QTimer::singleShot(10000, this, SLOT(logoutSoundTimeout()));
|
||||
kDebug() << "Starting logout event";
|
||||
state = WaitingForKNotify;
|
||||
createLogoutEffectWidget();
|
||||
n->send();
|
||||
|
||||
} else if ( state == Checkpoint ) {
|
||||
foreach( KSMClient* c, clients ) {
|
||||
SmsSaveComplete( c->connection());
|
||||
}
|
||||
state = Idle;
|
||||
} else { //ClosingSubSession
|
||||
startKillingSubSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void KSMServer::logoutSoundTimeout()
|
||||
{
|
||||
if (state != WaitingForKNotify) {
|
||||
return;
|
||||
}
|
||||
kDebug() << "logout sound timeout";
|
||||
logoutSoundFinished();
|
||||
}
|
||||
|
||||
void KSMServer::startKilling()
|
||||
{
|
||||
kDebug() << "Starting killing clients";
|
||||
// kill all clients
|
||||
state = Killing;
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if( isWM( c )) // kill the WM as the last one in order to reduce flicker
|
||||
continue;
|
||||
kDebug() << "completeShutdown: client " << c->program() << "(" << c->clientId() << ")";
|
||||
SmsDie( c->connection() );
|
||||
}
|
||||
|
||||
kDebug() << " We killed all clients. We have now clients.count()=" << clients.count();
|
||||
completeKilling();
|
||||
QTimer::singleShot( 10000, this, SLOT(timeoutQuit()) );
|
||||
}
|
||||
|
||||
void KSMServer::completeKilling()
|
||||
{
|
||||
kDebug() << "KSMServer::completeKilling clients.count()=" << clients.count();
|
||||
if( state == Killing ) {
|
||||
bool wait = false;
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if( isWM( c ))
|
||||
continue;
|
||||
wait = true; // still waiting for clients to go away
|
||||
}
|
||||
if( wait )
|
||||
return;
|
||||
killWM();
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::killWM()
|
||||
{
|
||||
if( state != Killing )
|
||||
return;
|
||||
delete logoutEffectWidget;
|
||||
kDebug() << "Starting killing WM";
|
||||
state = KillingWM;
|
||||
bool iswm = false;
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if( isWM( c )) {
|
||||
iswm = true;
|
||||
kDebug() << "killWM: client " << c->program() << "(" << c->clientId() << ")";
|
||||
SmsDie( c->connection() );
|
||||
}
|
||||
}
|
||||
if( iswm ) {
|
||||
completeKillingWM();
|
||||
QTimer::singleShot( 5000, this, SLOT(timeoutWMQuit()) );
|
||||
}
|
||||
else
|
||||
killingCompleted();
|
||||
}
|
||||
|
||||
void KSMServer::completeKillingWM()
|
||||
{
|
||||
kDebug() << "KSMServer::completeKillingWM clients.count()=" << clients.count();
|
||||
if( state == KillingWM ) {
|
||||
if( clients.isEmpty())
|
||||
killingCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
// shutdown is fully complete
|
||||
void KSMServer::killingCompleted()
|
||||
{
|
||||
kapp->quit();
|
||||
}
|
||||
|
||||
void KSMServer::logoutSoundFinished( )
|
||||
{
|
||||
if( state != WaitingForKNotify )
|
||||
return;
|
||||
kDebug() << "Logout event finished";
|
||||
startKilling();
|
||||
}
|
||||
|
||||
void KSMServer::timeoutQuit()
|
||||
{
|
||||
foreach( KSMClient* c, clients ) {
|
||||
kWarning() << "SmsDie timeout, client " << c->program() << "(" << c->clientId() << ")" ;
|
||||
}
|
||||
killWM();
|
||||
}
|
||||
|
||||
void KSMServer::timeoutWMQuit()
|
||||
{
|
||||
if( state == KillingWM ) {
|
||||
kWarning() << "SmsDie WM timeout" ;
|
||||
}
|
||||
killingCompleted();
|
||||
}
|
||||
|
||||
void KSMServer::createLogoutEffectWidget()
|
||||
{
|
||||
// Ok, this is rather a hack. In order to fade the whole desktop when playing the logout
|
||||
// sound, killing applications and leaving KDE, create a dummy window that triggers
|
||||
// the logout fade effect again.
|
||||
logoutEffectWidget = new QWidget( NULL, Qt::X11BypassWindowManagerHint );
|
||||
logoutEffectWidget->winId(); // workaround for Qt4.3 setWindowRole() assert
|
||||
logoutEffectWidget->setWindowRole( "logouteffect" );
|
||||
// Qt doesn't set this on unmanaged windows
|
||||
QByteArray appName = QApplication::applicationName().toLatin1();
|
||||
QByteArray appClass = QX11Info::appClass();
|
||||
XClassHint class_hint;
|
||||
class_hint.res_name = appName.data(); // application name
|
||||
class_hint.res_class = appClass.data(); // application class
|
||||
XSetWMProperties( QX11Info::display(), logoutEffectWidget->winId(),
|
||||
NULL, NULL, NULL, 0, NULL, NULL, &class_hint );
|
||||
XChangeProperty( QX11Info::display(), logoutEffectWidget->winId(),
|
||||
XInternAtom( QX11Info::display(), "WM_WINDOW_ROLE", False ), XA_STRING, 8, PropModeReplace,
|
||||
(unsigned char *)"logouteffect", strlen( "logouteffect" ));
|
||||
logoutEffectWidget->setGeometry( -100, -100, 1, 1 );
|
||||
logoutEffectWidget->show();
|
||||
}
|
||||
|
||||
void KSMServer::saveSubSession(const QString &name, QStringList saveAndClose, QStringList saveOnly)
|
||||
{
|
||||
if( state != Idle ) { // performing startup
|
||||
kDebug() << "not idle!" << state;
|
||||
return;
|
||||
}
|
||||
kDebug() << name << saveAndClose << saveOnly;
|
||||
state = ClosingSubSession;
|
||||
saveType = SmSaveBoth; //both or local? what oes it mean?
|
||||
saveSession = true;
|
||||
sessionGroup = "SubSession: " + name;
|
||||
|
||||
startProtection();
|
||||
foreach( KSMClient* c, clients ) {
|
||||
if (saveAndClose.contains(c->clientId())) {
|
||||
c->resetState();
|
||||
SmsSaveYourself( c->connection(), saveType,
|
||||
true, SmInteractStyleAny, false );
|
||||
clientsToSave << c;
|
||||
clientsToKill << c;
|
||||
} else if (saveOnly.contains(c->clientId())) {
|
||||
c->resetState();
|
||||
SmsSaveYourself( c->connection(), saveType,
|
||||
true, SmInteractStyleAny, false );
|
||||
clientsToSave << c;
|
||||
}
|
||||
}
|
||||
completeShutdownOrCheckpoint();
|
||||
}
|
||||
|
||||
void KSMServer::startKillingSubSession()
|
||||
{
|
||||
kDebug() << "Starting killing clients";
|
||||
// kill all clients
|
||||
state = KillingSubSession;
|
||||
foreach( KSMClient* c, clientsToKill ) {
|
||||
kDebug() << "completeShutdown: client " << c->program() << "(" << c->clientId() << ")";
|
||||
SmsDie( c->connection() );
|
||||
}
|
||||
|
||||
kDebug() << " We killed some clients. We have now clients.count()=" << clients.count();
|
||||
completeKillingSubSession();
|
||||
QTimer::singleShot( 10000, this, SLOT(signalSubSessionClosed()) );
|
||||
}
|
||||
|
||||
void KSMServer::completeKillingSubSession()
|
||||
{
|
||||
kDebug() << "KSMServer::completeKillingSubSession clients.count()=" << clients.count();
|
||||
if( state == KillingSubSession ) {
|
||||
bool wait = false;
|
||||
foreach( KSMClient* c, clientsToKill ) {
|
||||
if( isWM( c ))
|
||||
continue;
|
||||
wait = true; // still waiting for clients to go away
|
||||
}
|
||||
if( wait )
|
||||
return;
|
||||
signalSubSessionClosed();
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::signalSubSessionClosed()
|
||||
{
|
||||
if( state != KillingSubSession )
|
||||
return;
|
||||
clientsToKill.clear();
|
||||
clientsToSave.clear();
|
||||
//TODO tell the subSession manager the close request was carried out
|
||||
//so that plasma can close its stuff
|
||||
state = Idle;
|
||||
kDebug() << state;
|
||||
emit subSessionClosed();
|
||||
}
|
|
@ -1,499 +0,0 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
Copyright 2005 Lubos Lunak <l.lunak@kde.org>
|
||||
|
||||
relatively small extensions by Oswald Buddenhagen <ob6@inf.tu-dresden.de>
|
||||
|
||||
some code taken from the dcopserver (part of the KDE libraries), which is
|
||||
Copyright 1999 Matthias Ettrich <ettrich@kde.org>
|
||||
Copyright 1999 Preston Brown <pbrown@kde.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "config-unix.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include <klocale.h>
|
||||
#include <kglobal.h>
|
||||
#include <kconfig.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kapplication.h>
|
||||
#include <ktemporaryfile.h>
|
||||
#include <knotification.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "global.h"
|
||||
#include "server.h"
|
||||
#include "client.h"
|
||||
|
||||
#include <QtGui/qx11info_x11.h>
|
||||
|
||||
#include "kcminit_interface.h"
|
||||
|
||||
//#define KSMSERVER_STARTUP_DEBUG1
|
||||
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
static QTime t;
|
||||
#endif
|
||||
|
||||
/*! Restores the previous session. Ensures the window manager is
|
||||
running (if specified).
|
||||
*/
|
||||
void KSMServer::restoreSession( const QString &sessionName )
|
||||
{
|
||||
if( state != Idle )
|
||||
return;
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
t.start();
|
||||
#endif
|
||||
state = LaunchingWM;
|
||||
|
||||
kDebug() << "KSMServer::restoreSession " << sessionName;
|
||||
KSharedConfig::Ptr config = KGlobal::config();
|
||||
|
||||
sessionGroup = "Session: " + sessionName;
|
||||
KConfigGroup configSessionGroup( config, sessionGroup);
|
||||
|
||||
int count = configSessionGroup.readEntry( "count", 0 );
|
||||
appsToStart = count;
|
||||
connect( klauncherSignals, SIGNAL(autoStart0Done()), SLOT(autoStart0Done()));
|
||||
connect( klauncherSignals, SIGNAL(autoStart1Done()), SLOT(autoStart1Done()));
|
||||
connect( klauncherSignals, SIGNAL(autoStart2Done()), SLOT(autoStart2Done()));
|
||||
|
||||
// find all commands to launch the wm in the session
|
||||
QList<QStringList> wmStartCommands;
|
||||
if ( !wm.isEmpty() ) {
|
||||
for ( int i = 1; i <= count; i++ ) {
|
||||
QString n = QString::number(i);
|
||||
if ( isWM( configSessionGroup.readEntry( QString("program")+n, QString() ) ) ) {
|
||||
wmStartCommands << configSessionGroup.readEntry( QString("restartCommand")+n, QStringList() );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( wmStartCommands.isEmpty()) // otherwise use the configured default
|
||||
wmStartCommands << wmCommands;
|
||||
|
||||
launchWM( wmStartCommands );
|
||||
}
|
||||
|
||||
/*!
|
||||
Starts the default session.
|
||||
|
||||
Currently, that's the window manager only (if specified).
|
||||
*/
|
||||
void KSMServer::startDefaultSession()
|
||||
{
|
||||
if( state != Idle )
|
||||
return;
|
||||
state = LaunchingWM;
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
t.start();
|
||||
#endif
|
||||
sessionGroup = "";
|
||||
connect( klauncherSignals, SIGNAL(autoStart0Done()), SLOT(autoStart0Done()));
|
||||
connect( klauncherSignals, SIGNAL(autoStart1Done()), SLOT(autoStart1Done()));
|
||||
connect( klauncherSignals, SIGNAL(autoStart2Done()), SLOT(autoStart2Done()));
|
||||
|
||||
launchWM( QList< QStringList >() << wmCommands );
|
||||
}
|
||||
|
||||
void KSMServer::launchWM( const QList< QStringList >& wmStartCommands )
|
||||
{
|
||||
assert( state == LaunchingWM );
|
||||
|
||||
// when we have a window manager, we start it first and give
|
||||
// it some time before launching other processes. Results in a
|
||||
// visually more appealing startup.
|
||||
QStringList wmCommand = wmStartCommands[0];
|
||||
QString program = wmCommand.takeAt(0);
|
||||
connect( wmProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(wmProcessChange()));
|
||||
connect( wmProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(wmProcessChange()));
|
||||
wmProcess->start(program, wmCommand);
|
||||
wmProcess->waitForStarted(4000);
|
||||
QMetaObject::invokeMethod(this, "autoStart0", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void KSMServer::clientSetProgram( KSMClient* client )
|
||||
{
|
||||
if( client->program() == wm )
|
||||
autoStart0();
|
||||
}
|
||||
|
||||
void KSMServer::wmProcessChange()
|
||||
{
|
||||
if( state != LaunchingWM ) {
|
||||
// don't care about the process when not in the wm-launching state anymore
|
||||
disconnect(wmProcess, 0, this, 0);
|
||||
return;
|
||||
}
|
||||
if( wmProcess->state() == QProcess::NotRunning ) {
|
||||
// wm failed to launch for some reason, go with kwin instead
|
||||
kWarning() << "Window manager" << wm << "failed to launch";
|
||||
if( wm == "kwin" )
|
||||
return; // uhoh, kwin itself failed
|
||||
kDebug() << "Launching KWin";
|
||||
wm = "kwin";
|
||||
wmCommands = ( QStringList() << "kwin" );
|
||||
// launch it
|
||||
launchWM( QList< QStringList >() << wmCommands );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::autoStart0()
|
||||
{
|
||||
if( state != LaunchingWM )
|
||||
return;
|
||||
if( !checkStartupSuspend())
|
||||
return;
|
||||
state = AutoStart0;
|
||||
|
||||
static const QString kdedInterface = QString::fromLatin1("org.kde.kded");
|
||||
QDBusConnectionInterface* sessionInterface = QDBusConnection::sessionBus().interface();
|
||||
if (!sessionInterface->isServiceRegistered(kdedInterface)) {
|
||||
sessionInterface->startService(kdedInterface);
|
||||
}
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << t.elapsed();
|
||||
#endif
|
||||
|
||||
klauncherSignals->asyncCall("autoStart", int(0));
|
||||
}
|
||||
|
||||
void KSMServer::autoStart0Done()
|
||||
{
|
||||
if( state != AutoStart0 )
|
||||
return;
|
||||
disconnect( klauncherSignals, SIGNAL(autoStart0Done()), this, SLOT(autoStart0Done()));
|
||||
if( !checkStartupSuspend())
|
||||
return;
|
||||
kDebug() << "Autostart 0 done";
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << t.elapsed();
|
||||
#endif
|
||||
state = KcmInitPhase1;
|
||||
kcminitSignals = new QDBusInterface("org.kde.kcminit", "/kcminit", "org.kde.KCMInit", QDBusConnection::sessionBus(), this );
|
||||
if( !kcminitSignals->isValid()) {
|
||||
kWarning() << "kcminit not running? If we are running with mobile profile or in another platform other than X11 this is normal.";
|
||||
delete kcminitSignals;
|
||||
kcminitSignals = 0;
|
||||
QMetaObject::invokeMethod(this, "kcmPhase1Done", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
connect( kcminitSignals, SIGNAL(phase1Done()), SLOT(kcmPhase1Done()));
|
||||
QTimer::singleShot( 10000, this, SLOT(kcmPhase1Timeout())); // protection
|
||||
|
||||
org::kde::KCMInit kcminit("org.kde.kcminit", "/kcminit" , QDBusConnection::sessionBus());
|
||||
kcminit.runPhase1();
|
||||
}
|
||||
|
||||
void KSMServer::kcmPhase1Done()
|
||||
{
|
||||
if( state != KcmInitPhase1 )
|
||||
return;
|
||||
kDebug() << "Kcminit phase 1 done";
|
||||
if (kcminitSignals) {
|
||||
disconnect( kcminitSignals, SIGNAL(phase1Done()), this, SLOT(kcmPhase1Done()));
|
||||
}
|
||||
autoStart1();
|
||||
}
|
||||
|
||||
void KSMServer::kcmPhase1Timeout()
|
||||
{
|
||||
if( state != KcmInitPhase1 )
|
||||
return;
|
||||
kDebug() << "Kcminit phase 1 timeout";
|
||||
kcmPhase1Done();
|
||||
}
|
||||
|
||||
void KSMServer::autoStart1()
|
||||
{
|
||||
if( state != KcmInitPhase1 )
|
||||
return;
|
||||
state = AutoStart1;
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << t.elapsed();
|
||||
#endif
|
||||
klauncherSignals->asyncCall("autoStart", int(1));
|
||||
}
|
||||
|
||||
void KSMServer::autoStart1Done()
|
||||
{
|
||||
if( state != AutoStart1 )
|
||||
return;
|
||||
disconnect( klauncherSignals, SIGNAL(autoStart1Done()), this, SLOT(autoStart1Done()));
|
||||
if( !checkStartupSuspend())
|
||||
return;
|
||||
kDebug() << "Autostart 1 done";
|
||||
setupShortcuts(); // done only here, because it needs kglobalaccel :-/
|
||||
lastAppStarted = 0;
|
||||
lastIdStarted.clear();
|
||||
state = Restoring;
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << t.elapsed();
|
||||
#endif
|
||||
if( defaultSession()) {
|
||||
autoStart2();
|
||||
return;
|
||||
}
|
||||
tryRestoreNext();
|
||||
}
|
||||
|
||||
void KSMServer::clientRegistered( const char* previousId )
|
||||
{
|
||||
if ( previousId && lastIdStarted == previousId )
|
||||
tryRestoreNext();
|
||||
}
|
||||
|
||||
void KSMServer::tryRestoreNext()
|
||||
{
|
||||
if( state != Restoring && state != RestoringSubSession )
|
||||
return;
|
||||
restoreTimer.stop();
|
||||
startupSuspendTimeoutTimer.stop();
|
||||
KConfigGroup config(KGlobal::config(), sessionGroup );
|
||||
|
||||
while ( lastAppStarted < appsToStart ) {
|
||||
lastAppStarted++;
|
||||
QString n = QString::number(lastAppStarted);
|
||||
QString clientId = config.readEntry( QString("clientId")+n, QString() );
|
||||
bool alreadyStarted = false;
|
||||
foreach ( KSMClient *c, clients ) {
|
||||
if ( c->clientId() == clientId ) {
|
||||
alreadyStarted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( alreadyStarted )
|
||||
continue;
|
||||
|
||||
QStringList restartCommand = config.readEntry( QString("restartCommand")+n, QStringList() );
|
||||
if ( restartCommand.isEmpty() ||
|
||||
(config.readEntry( QString("restartStyleHint")+n, 0 ) == SmRestartNever)) {
|
||||
continue;
|
||||
}
|
||||
if ( isWM( config.readEntry( QString("program")+n, QString() ) ) )
|
||||
continue; // wm already started
|
||||
if( config.readEntry( QString( "wasWm" )+n, false ))
|
||||
continue; // it was wm before, but not now, don't run it (some have --replace in command :( )
|
||||
startApplication( restartCommand,
|
||||
config.readEntry( QString("clientMachine")+n, QString() ),
|
||||
config.readEntry( QString("userId")+n, QString() ));
|
||||
lastIdStarted = clientId;
|
||||
if ( !lastIdStarted.isEmpty() ) {
|
||||
restoreTimer.setSingleShot( true );
|
||||
restoreTimer.start( 2000 );
|
||||
return; // we get called again from the clientRegistered handler
|
||||
}
|
||||
}
|
||||
|
||||
//all done
|
||||
appsToStart = 0;
|
||||
lastIdStarted.clear();
|
||||
|
||||
if (state == Restoring)
|
||||
autoStart2();
|
||||
else { //subsession
|
||||
state = Idle;
|
||||
emit subSessionOpened();
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::autoStart2()
|
||||
{
|
||||
if( state != Restoring )
|
||||
return;
|
||||
if( !checkStartupSuspend())
|
||||
return;
|
||||
state = FinishingStartup;
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << t.elapsed();
|
||||
#endif
|
||||
waitAutoStart2 = true;
|
||||
waitKcmInit2 = true;
|
||||
klauncherSignals->asyncCall("autoStart", int(2));
|
||||
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << "klauncher" << t.elapsed();
|
||||
#endif
|
||||
|
||||
QDBusInterface kded( "org.kde.kded", "/kded", "org.kde.kded" );
|
||||
QDBusPendingCall pendingcall = kded.asyncCall( "loadSecondPhase" );
|
||||
while (!pendingcall.isFinished()) {
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << "kded" << t.elapsed();
|
||||
#endif
|
||||
|
||||
if (kcminitSignals) {
|
||||
connect( kcminitSignals, SIGNAL(phase2Done()), SLOT(kcmPhase2Done()));
|
||||
QTimer::singleShot( 10000, this, SLOT(kcmPhase2Timeout())); // protection
|
||||
org::kde::KCMInit kcminit("org.kde.kcminit", "/kcminit" , QDBusConnection::sessionBus());
|
||||
kcminit.runPhase2();
|
||||
} else {
|
||||
QMetaObject::invokeMethod(this, "kcmPhase2Done", Qt::QueuedConnection);
|
||||
}
|
||||
KNotification::event("kde/startkde"); // this is the time KDE is up, more or less
|
||||
}
|
||||
|
||||
void KSMServer::autoStart2Done()
|
||||
{
|
||||
if( state != FinishingStartup )
|
||||
return;
|
||||
disconnect( klauncherSignals, SIGNAL(autoStart2Done()), this, SLOT(autoStart2Done()));
|
||||
kDebug() << "Autostart 2 done";
|
||||
waitAutoStart2 = false;
|
||||
finishStartup();
|
||||
}
|
||||
|
||||
void KSMServer::kcmPhase2Done()
|
||||
{
|
||||
if( state != FinishingStartup )
|
||||
return;
|
||||
kDebug() << "Kcminit phase 2 done";
|
||||
if (kcminitSignals) {
|
||||
disconnect( kcminitSignals, SIGNAL(phase2Done()), this, SLOT(kcmPhase2Done()));
|
||||
delete kcminitSignals;
|
||||
kcminitSignals = 0;
|
||||
}
|
||||
waitKcmInit2 = false;
|
||||
finishStartup();
|
||||
}
|
||||
|
||||
void KSMServer::kcmPhase2Timeout()
|
||||
{
|
||||
if( !waitKcmInit2 )
|
||||
return;
|
||||
kDebug() << "Kcminit phase 2 timeout";
|
||||
kcmPhase2Done();
|
||||
}
|
||||
|
||||
void KSMServer::finishStartup()
|
||||
{
|
||||
if( state != FinishingStartup )
|
||||
return;
|
||||
if( waitAutoStart2 || waitKcmInit2 )
|
||||
return;
|
||||
|
||||
#ifdef KSMSERVER_STARTUP_DEBUG1
|
||||
kDebug() << t.elapsed();
|
||||
#endif
|
||||
|
||||
state = Idle;
|
||||
setupXIOErrorHandler(); // From now on handle X errors as normal shutdown.
|
||||
}
|
||||
|
||||
bool KSMServer::checkStartupSuspend()
|
||||
{
|
||||
if( startupSuspendCount.isEmpty())
|
||||
return true;
|
||||
// wait for the phase to finish
|
||||
if( !startupSuspendTimeoutTimer.isActive())
|
||||
{
|
||||
startupSuspendTimeoutTimer.setSingleShot( true );
|
||||
startupSuspendTimeoutTimer.start( 10000 );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void KSMServer::suspendStartup( const QString &app )
|
||||
{
|
||||
if( !startupSuspendCount.contains( app ))
|
||||
startupSuspendCount[ app ] = 0;
|
||||
++startupSuspendCount[ app ];
|
||||
}
|
||||
|
||||
void KSMServer::resumeStartup( const QString &app )
|
||||
{
|
||||
if( !startupSuspendCount.contains( app ))
|
||||
return;
|
||||
if( --startupSuspendCount[ app ] == 0 ) {
|
||||
startupSuspendCount.remove( app );
|
||||
if( startupSuspendCount.isEmpty() && startupSuspendTimeoutTimer.isActive()) {
|
||||
startupSuspendTimeoutTimer.stop();
|
||||
resumeStartupInternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::startupSuspendTimeout()
|
||||
{
|
||||
kDebug() << "Startup suspend timeout:" << state;
|
||||
resumeStartupInternal();
|
||||
}
|
||||
|
||||
void KSMServer::resumeStartupInternal()
|
||||
{
|
||||
startupSuspendCount.clear();
|
||||
switch( state ) {
|
||||
case LaunchingWM:
|
||||
autoStart0();
|
||||
break;
|
||||
case AutoStart0:
|
||||
autoStart0Done();
|
||||
break;
|
||||
case AutoStart1:
|
||||
autoStart1Done();
|
||||
break;
|
||||
case Restoring:
|
||||
autoStart2();
|
||||
break;
|
||||
default:
|
||||
kWarning() << "Unknown resume startup state" ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KSMServer::restoreSubSession( const QString& name )
|
||||
{
|
||||
sessionGroup = "SubSession: " + name;
|
||||
|
||||
KConfigGroup configSessionGroup( KGlobal::config(), sessionGroup);
|
||||
int count = configSessionGroup.readEntry( "count", 0 );
|
||||
appsToStart = count;
|
||||
lastAppStarted = 0;
|
||||
lastIdStarted.clear();
|
||||
|
||||
state = RestoringSubSession;
|
||||
tryRestoreNext();
|
||||
}
|
|
@ -130,11 +130,6 @@ qt4_add_dbus_adaptor(kwin_SRCS org.kde.KWin.xml dbusinterface.h KWin::DBusInterf
|
|||
qt4_add_dbus_adaptor(kwin_SRCS org.kde.kwin.Compositing.xml composite.h KWin::Compositor)
|
||||
qt4_add_dbus_adaptor(kwin_SRCS org.kde.kwin.Effects.xml effects.h KWin::EffectsHandlerImpl)
|
||||
|
||||
qt4_add_dbus_interface(kwin_SRCS
|
||||
${CMAKE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml
|
||||
ksmserver_interface
|
||||
)
|
||||
|
||||
########### target link libraries ###############
|
||||
|
||||
if (NOT X11_xf86vmode_FOUND)
|
||||
|
|
|
@ -147,7 +147,7 @@ void LogoutEffect::slotWindowDeleted(EffectWindow* w)
|
|||
bool LogoutEffect::isLogoutDialog(EffectWindow* w)
|
||||
{
|
||||
// TODO there should be probably a better way (window type?)
|
||||
if (w->windowClass() == "ksmserver ksmserver"
|
||||
if (w->windowClass() == "plasma-desktop plasma-desktop"
|
||||
&& (w->windowRole() == "logoutdialog" || w->windowRole() == "logouteffect")) {
|
||||
return true;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ void LogoutEffect::slotPropertyNotify(EffectWindow* w, long a)
|
|||
return;
|
||||
}
|
||||
|
||||
// We are using a compatible KSMServer therefore only terminate the effect when the
|
||||
// using a compatible session manager therefore only terminate the effect when the
|
||||
// atom is deleted, not when the dialog is closed.
|
||||
canDoPersistent = true;
|
||||
effects->addRepaintFull();
|
||||
|
|
|
@ -32,6 +32,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#endif // HAVE_MALLOC_H
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusInterface>
|
||||
#include <QMessageBox>
|
||||
#include <QEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
@ -53,8 +55,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <QtGui/qx11info_x11.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
#include <ksmserver_interface.h>
|
||||
|
||||
#include "atoms.h"
|
||||
#include "options.h"
|
||||
#include "sm.h"
|
||||
|
@ -335,10 +335,14 @@ int main(int argc, char * argv[])
|
|||
KCmdLineArgs::addCmdLineOptions(args);
|
||||
|
||||
KWin::Application a;
|
||||
org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
|
||||
ksmserver.suspendStartup("kwin");
|
||||
QDBusInterface plasma("org.kde.plasma-desktop", "/App", "local.PlasmaApp", QDBusConnection::sessionBus());
|
||||
if (plasma.isValid()) {
|
||||
plasma.call("suspendStartup", "kwin");
|
||||
}
|
||||
if (!a.setup()) {
|
||||
ksmserver.resumeStartup("kwin");
|
||||
if (plasma.isValid()) {
|
||||
plasma.call("resumeStartup", "kwin");
|
||||
}
|
||||
a.exit(1);
|
||||
return 1;
|
||||
}
|
||||
|
@ -354,7 +358,9 @@ int main(int argc, char * argv[])
|
|||
// and one more iteration just in case
|
||||
a.processEvents();
|
||||
|
||||
ksmserver.resumeStartup("kwin");
|
||||
if (plasma.isValid()) {
|
||||
plasma.call("resumeStartup", "kwin");
|
||||
}
|
||||
KWin::SessionManager weAreIndeed;
|
||||
KWin::SessionSaveDoneHelper helper;
|
||||
KGlobal::locale()->insertCatalog("kwin_effects");
|
||||
|
|
10
kwin/sm.cpp
10
kwin/sm.cpp
|
@ -39,24 +39,24 @@ namespace KWin
|
|||
|
||||
bool SessionManager::saveState(QSessionManager& sm)
|
||||
{
|
||||
// If the session manager is ksmserver, save stacking
|
||||
// If the session manager is plasma-desktop, save stacking
|
||||
// order, active window, active desktop etc. in phase 1,
|
||||
// as ksmserver assures no interaction will be done
|
||||
// as plasma-desktop assures no interaction will be done
|
||||
// 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)
|
||||
char* sm_vendor = SmcVendor(static_cast< SmcConn >(sm.handle()));
|
||||
bool ksmserver = qstrcmp(sm_vendor, "KDE") == 0;
|
||||
bool kde = qstrcmp(sm_vendor, "KDE") == 0;
|
||||
free(sm_vendor);
|
||||
if (!sm.isPhase2()) {
|
||||
Workspace::self()->sessionSaveStarted();
|
||||
if (ksmserver) // save stacking order etc. before "save file?" etc. dialogs change it
|
||||
if (kde) // save stacking order etc. before "save file?" etc. dialogs change it
|
||||
Workspace::self()->storeSession(kapp->sessionConfig(), SMSavePhase0);
|
||||
sm.release(); // Qt doesn't automatically release in this case (bug?)
|
||||
sm.requestPhase2();
|
||||
return true;
|
||||
}
|
||||
Workspace::self()->storeSession(kapp->sessionConfig(), ksmserver ? SMSavePhase2 : SMSavePhase2Full);
|
||||
Workspace::self()->storeSession(kapp->sessionConfig(), kde ? SMSavePhase2 : SMSavePhase2Full);
|
||||
kapp->sessionConfig()->sync();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ set(kworkspace_LIB_SRCS
|
|||
)
|
||||
|
||||
|
||||
set(ksmserver_xml ${CMAKE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml)
|
||||
qt4_add_dbus_interface(kworkspace_LIB_SRCS ${ksmserver_xml} ksmserver_interface)
|
||||
set(plasma_xml ${CMAKE_SOURCE_DIR}/plasma/shells/plasma-desktop/dbus/org.kde.plasma.App.xml)
|
||||
qt4_add_dbus_interface(kworkspace_LIB_SRCS ${plasma_xml} plasma_interface)
|
||||
|
||||
set(kwin_xml ${CMAKE_SOURCE_DIR}/kwin/org.kde.KWin.xml)
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "kworkspace.h"
|
||||
#include "kdisplaymanager.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDataStream>
|
||||
|
@ -31,7 +32,7 @@
|
|||
#include <klocale.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kuser.h>
|
||||
#include <ksmserver_interface.h>
|
||||
#include <plasma_interface.h>
|
||||
|
||||
#include <stdlib.h> // getenv()
|
||||
#include <sys/types.h>
|
||||
|
@ -167,12 +168,12 @@ static void cleanup_sm()
|
|||
void requestShutDown(ShutdownConfirm confirm, ShutdownType sdtype)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
/* use ksmserver's dcop interface if necessary */
|
||||
/* use plasma's dcop interface if necessary */
|
||||
if ( confirm == ShutdownConfirmYes ||
|
||||
sdtype != ShutdownTypeDefault )
|
||||
{
|
||||
org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
|
||||
ksmserver.logout((int)confirm, (int)sdtype);
|
||||
local::PlasmaApp plasma("org.kde.plasma-desktop", "/App", QDBusConnection::sessionBus());
|
||||
plasma.logout((int)confirm, (int)sdtype);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -191,12 +192,7 @@ bool canShutDown( ShutdownConfirm confirm, ShutdownType sdtype )
|
|||
if ( confirm == ShutdownConfirmYes ||
|
||||
sdtype != ShutdownTypeDefault )
|
||||
{
|
||||
org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
|
||||
QDBusReply<bool> reply = ksmserver.canShutdown();
|
||||
if (!reply.isValid()) {
|
||||
return false;
|
||||
}
|
||||
return reply;
|
||||
return KDisplayManager().canShutdown();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace KWorkSpace
|
|||
* Asks the session manager to shut the session down.
|
||||
*
|
||||
* Using @p confirm == ShutdownConfirmYes or @p sdtype != ShutdownTypeDefault
|
||||
* causes the use of ksmserver's D-Bus interface. The remaining two
|
||||
* causes the use of plasma's D-Bus interface. The remaining two
|
||||
* combinations use the standard XSMP and will work with any session manager
|
||||
* compliant with it.
|
||||
*
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
namespace KWorkSpace
|
||||
{
|
||||
|
||||
// A class that creates another connection to ksmserver and handles it properly.
|
||||
// A class that creates another connection to plasma and handles it properly.
|
||||
class KRequestShutdownHelper
|
||||
: public QObject
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
enum DoWhat {
|
||||
DoNothing = 0,
|
||||
DoSwitch = 1,
|
||||
// shutdown is asked for by ksmserver
|
||||
// shutdown is asked for by plasma-desktop
|
||||
DoToRam = 2,
|
||||
DoToDisk = 3,
|
||||
DoHybrid = 4
|
||||
|
|
|
@ -15,6 +15,7 @@ set(plasma_SRCS
|
|||
panelappletoverlay.cpp
|
||||
plasmaapp.cpp
|
||||
positioningruler.cpp
|
||||
shutdowndlg.cpp
|
||||
)
|
||||
|
||||
set(plasmaapp_dbusXML dbus/org.kde.plasma.App.xml)
|
||||
|
@ -37,11 +38,6 @@ install(
|
|||
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES data/plasma-desktop.desktop
|
||||
DESTINATION ${KDE4_AUTOSTART_INSTALL_DIR}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES data/plasma-desktoprc
|
||||
DESTINATION ${KDE4_CONFIG_INSTALL_DIR}
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Exec=plasma-desktop
|
||||
Name=Plasma Desktop Workspace
|
||||
Name[ar]=مساحة عمل بلازما
|
||||
Name[ast]=Espaciu de trabayu del escritoriu Plasma
|
||||
Name[be@latin]=Rabočy abšar stała „Plasma”
|
||||
Name[bg]=Работно пространство Plasma
|
||||
Name[bs]=Plazma radni prostor površi
|
||||
Name[ca]=Espai de treball de l'escriptori Plasma
|
||||
Name[ca@valencia]=Espai de treball de l'escriptori Plasma
|
||||
Name[cs]=Pracovní plocha Plasma
|
||||
Name[da]=Plasma Desktop Workspace
|
||||
Name[de]=Plasma-Arbeitsflächenbereiche
|
||||
Name[el]=Χώρος επιφάνειας εργασίας Plasma
|
||||
Name[en_GB]=Plasma Desktop Workspace
|
||||
Name[eo]=Plasma Labortabla laborspaco
|
||||
Name[es]=Espacio de trabajo del escritorio Plasma
|
||||
Name[et]=Plasma töölaua töötsoon
|
||||
Name[eu]=Plasma mahaigainaren laneko eremua
|
||||
Name[fi]=Plasma-työpöytä
|
||||
Name[fr]=Espace de travail Plasma
|
||||
Name[fy]=Plasma buroblêd wurkromte
|
||||
Name[ga]=Spás Oibre Deisce Plasma
|
||||
Name[gl]=Espazo de traballo do escritorio Plasma
|
||||
Name[gu]=પ્લાઝમા ડેસ્કટોપ વર્કસ્પેશ
|
||||
Name[he]=סביבת העבודה של Plasma
|
||||
Name[hi]=प्लाज्मा डेस्कटॉप कार्यस्थान
|
||||
Name[hne]=प्लाज्मा डेस्कटाप काम करे के जगह
|
||||
Name[hr]=Plasma radno okruženje
|
||||
Name[hu]=Plazma munkaterület
|
||||
Name[ia]=Spatio de labor de scriptorio de Plasma
|
||||
Name[id]=Ruang Kerja Desktop Plasma
|
||||
Name[is]=Vinnurýmd Plasma skjáborðs
|
||||
Name[it]=Spazio di lavoro del desktop di Plasma
|
||||
Name[kk]=Plasma үстел жұмыс орны
|
||||
Name[km]=តំបន់ការងារផ្ទៃតុរបស់ប្លាស្មា
|
||||
Name[kn]=ಪ್ಲಾಸ್ಮಾ ಗಣಕತೆರೆ ಕಾರ್ಯವ್ಯೋಮ (ವರ್ಕ್ ಸ್ಪೇಸ್)
|
||||
Name[ko]=Plasma 데스크톱 작업 공간
|
||||
Name[lt]=Plasma darbastalio erdvė
|
||||
Name[lv]=Plasma darbvirsma
|
||||
Name[ml]=പ്ലാസ്മ പണിയിടസ്ഥലം
|
||||
Name[mr]=Plasma डेस्कटॉप कार्यक्षेत्र
|
||||
Name[nb]=Arbeidsrom for Plasma skrivebord
|
||||
Name[nds]=Plasma-Schriefdischarbeitrebeet
|
||||
Name[nl]=Plasma Bureaublad Werkplek
|
||||
Name[nn]=Arbeidsområde for Plasma-skrivebord
|
||||
Name[or]=ପ୍ଲାଜମା ଡ଼େସ୍କଟପ କାର୍ଯ୍ୟସ୍ଥଳ
|
||||
Name[pa]=ਪਲਾਜ਼ਮਾ ਡੈਸਕਟਾਪ ਵਰਕਸਪੇਸ
|
||||
Name[pl]=Przestrzeń pulpitu Plazmy
|
||||
Name[pt]=Área de Trabalho do Plasma
|
||||
Name[pt_BR]=Espaço de Trabalho Plasma
|
||||
Name[ro]=Spațiu de lucru Plasma al biroului
|
||||
Name[ru]=Рабочий стол Plasma
|
||||
Name[si]=ප්ලාස්මා වැඩතල වැඩබිම
|
||||
Name[sk]=Pracovná plocha Plasma
|
||||
Name[sl]=Delovni prostor Plasma Desktop
|
||||
Name[sr]=Плазма, радни простор површи
|
||||
Name[sr@ijekavian]=Плазма, радни простор површи
|
||||
Name[sr@ijekavianlatin]=Plasma, radni prostor površi
|
||||
Name[sr@latin]=Plasma, radni prostor površi
|
||||
Name[sv]=Plasma arbetsområde för skrivbordet
|
||||
Name[ta]=Plasma Desktop Workspace
|
||||
Name[te]=ప్లాస్మా రంగస్థల పనిప్రదేశము
|
||||
Name[tg]=Муҳити мизи кории Plasma
|
||||
Name[th]=ขอบเขตพื้นที่ใช้งานของพลาสมา
|
||||
Name[tr]=Plasma Masaüstü Çalışma Alanı
|
||||
Name[ug]=پلازما ئۈستەلئۈستى خىزمەت بوشلۇقى
|
||||
Name[uk]=Робочий простір стільниці Плазми
|
||||
Name[wa]=Espåce di boutaedje Sicribanne di Plasma
|
||||
Name[x-test]=xxPlasma Desktop Workspacexx
|
||||
Name[zh_CN]=Plasma 桌面工作空间
|
||||
Name[zh_TW]=Plasma 桌面工作空間
|
||||
Type=Service
|
||||
StartupNotify=false
|
||||
OnlyShowIn=KDE;
|
||||
X-KDE-autostart-phase=0
|
||||
|
|
@ -10,5 +10,16 @@
|
|||
<method name="supportInformation">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="suspendStartup">
|
||||
<arg type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="resumeStartup">
|
||||
<arg type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="logout">
|
||||
<arg type="i" direction="in"/>
|
||||
<arg type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="wmChanged"/>
|
||||
</interface>
|
||||
</node>
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include <KActionCollection>
|
||||
#include <KToolInvocation>
|
||||
#include <KConfigSkeleton>
|
||||
#include <KDesktopFile>
|
||||
#include <KShell>
|
||||
|
||||
#include <Plasma/AbstractToolBox>
|
||||
#include <Plasma/Containment>
|
||||
|
@ -59,12 +61,17 @@
|
|||
#include "panelshadows.h"
|
||||
#include "panelview.h"
|
||||
#include "toolbutton.h"
|
||||
#include "shutdowndlg.h"
|
||||
#include "kworkspace/kdisplaymanager.h"
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
static const QString s_defaultwm = QString::fromLatin1("kwin");
|
||||
static const QStringList s_defaultwmcommands = QStringList() << s_defaultwm;
|
||||
|
||||
static void addInformationForApplet(QTextStream &stream, Plasma::Applet *applet)
|
||||
{
|
||||
if (applet->isContainment()) {
|
||||
|
@ -100,7 +107,14 @@ PlasmaApp* PlasmaApp::self()
|
|||
PlasmaApp::PlasmaApp()
|
||||
: KUniqueApplication(),
|
||||
m_corona(nullptr),
|
||||
m_panelHidden(0)
|
||||
m_panelHidden(0),
|
||||
m_phase(0),
|
||||
m_klauncher(nullptr),
|
||||
m_kcminit(nullptr),
|
||||
m_wmproc(nullptr),
|
||||
m_startupsuspend(0),
|
||||
m_dialogActive(false),
|
||||
m_sdtype(KWorkSpace::ShutdownTypeNone)
|
||||
{
|
||||
kDebug() << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "plasma app ctor start" << "(line:" << __LINE__ << ")";
|
||||
|
||||
|
@ -131,12 +145,76 @@ PlasmaApp::PlasmaApp()
|
|||
action->setGlobalShortcut(QKeySequence(Qt::CTRL+Qt::Key_Print));
|
||||
connect(action, SIGNAL(triggered(bool)), SLOT(captureCurrentWindow()));
|
||||
|
||||
action = actionCollection->addAction("Log Out");
|
||||
action->setText(i18n("Log Out"));
|
||||
action->setGlobalShortcut(QKeySequence(Qt::ALT+Qt::CTRL+Qt::Key_Delete));
|
||||
connect(action, SIGNAL(triggered(bool)), SLOT(defaultLogout()));
|
||||
|
||||
action = actionCollection->addAction("Log Out Without Confirmation");
|
||||
action->setText(i18n("Log Out Without Confirmation"));
|
||||
action->setGlobalShortcut(QKeySequence(Qt::ALT+Qt::CTRL+Qt::SHIFT+Qt::Key_Delete));
|
||||
connect(action, SIGNAL(triggered(bool)), SLOT(logoutWithoutConfirmation()));
|
||||
|
||||
action = actionCollection->addAction("Halt Without Confirmation");
|
||||
action->setText(i18n("Halt Without Confirmation"));
|
||||
action->setGlobalShortcut(QKeySequence(Qt::ALT+Qt::CTRL+Qt::SHIFT+Qt::Key_PageDown));
|
||||
connect(action, SIGNAL(triggered(bool)), SLOT(haltWithoutConfirmation()));
|
||||
|
||||
action = actionCollection->addAction("Reboot Without Confirmation");
|
||||
action->setText(i18n("Reboot Without Confirmation"));
|
||||
action->setGlobalShortcut(QKeySequence(Qt::ALT+Qt::CTRL+Qt::SHIFT+Qt::Key_PageUp));
|
||||
connect(action, SIGNAL(triggered(bool)), SLOT(rebootWithoutConfirmation()));
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(setupDesktop()));
|
||||
kDebug() << "!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) << "plasma app ctor end" << "(line:" << __LINE__ << ")";
|
||||
|
||||
m_klauncher = new QDBusInterface(
|
||||
QLatin1String("org.kde.klauncher"),
|
||||
QLatin1String("/KLauncher"),
|
||||
QLatin1String("org.kde.KLauncher"),
|
||||
QDBusConnection::sessionBus(),
|
||||
this
|
||||
);
|
||||
// TODO: m_klauncher->call("setLaunchEnv", "SESSION_MANAGER", "TODO");
|
||||
|
||||
|
||||
m_kcminit = new QDBusInterface(
|
||||
QLatin1String("org.kde.kcminit"),
|
||||
QLatin1String("/kcminit"),
|
||||
QLatin1String("org.kde.KCMInit"),
|
||||
QDBusConnection::sessionBus(),
|
||||
this
|
||||
);
|
||||
|
||||
KGlobal::dirs()->addResourceType("windowmanagers", "data", "plasma/windowmanagers");
|
||||
|
||||
QStringList wmcommands;
|
||||
if (qgetenv("KDE_FAILSAFE").toInt() != 1) {
|
||||
KConfig cfg("plasmarc", KConfig::NoGlobals);
|
||||
KConfigGroup config(&cfg, "General");
|
||||
const QString wmname = config.readEntry("windowManager", s_defaultwm);
|
||||
if (wmname != s_defaultwm) {
|
||||
KDesktopFile wmfile("windowmanagers", wmname + ".desktop");
|
||||
if (!wmfile.noDisplay() && wmfile.tryExec()) {
|
||||
wmcommands = KShell::splitArgs(wmfile.desktopGroup().readEntry("Exec"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wmcommands.isEmpty()) {
|
||||
wmcommands = s_defaultwmcommands;
|
||||
}
|
||||
const QString wmprog = wmcommands.takeFirst();
|
||||
m_wmproc = new QProcess(this);
|
||||
m_wmproc->start(wmprog, wmcommands);
|
||||
m_wmproc->waitForStarted(4000);
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(nextPhase()));
|
||||
}
|
||||
|
||||
PlasmaApp::~PlasmaApp()
|
||||
{
|
||||
cleanup();
|
||||
|
||||
if (m_corona) {
|
||||
m_corona->saveLayout(KStandardDirs::locateLocal("config", "plasma-desktoprc"));
|
||||
|
||||
|
@ -876,6 +954,44 @@ QString PlasmaApp::supportInformation() const
|
|||
return streambuffer;
|
||||
}
|
||||
|
||||
void PlasmaApp::suspendStartup(const QString &app)
|
||||
{
|
||||
// TODO: timeout for suspending
|
||||
m_startupsuspend++;
|
||||
}
|
||||
|
||||
void PlasmaApp::resumeStartup(const QString &app)
|
||||
{
|
||||
m_startupsuspend--;
|
||||
}
|
||||
|
||||
void PlasmaApp::logout(int confirm, int sdtype)
|
||||
{
|
||||
// TODO: prevent logout while initializing
|
||||
m_sdtype = static_cast<KWorkSpace::ShutdownType>(sdtype);
|
||||
if (confirm == KWorkSpace::ShutdownConfirmNo) {
|
||||
QTimer::singleShot(500, this, SLOT(doLogout()));
|
||||
return;
|
||||
}
|
||||
if (m_dialogActive) {
|
||||
return;
|
||||
}
|
||||
m_dialogActive = true;
|
||||
KApplication::kApplication()->updateUserTimestamp();
|
||||
const bool maysd = KDisplayManager().canShutdown();
|
||||
const bool choose = (m_sdtype == KWorkSpace::ShutdownTypeDefault);
|
||||
const bool logoutConfirmed = KSMShutdownDlg::confirmShutdown(maysd, choose, m_sdtype);
|
||||
if (logoutConfirmed) {
|
||||
QTimer::singleShot(500, this, SLOT(doLogout()));
|
||||
}
|
||||
m_dialogActive = false;
|
||||
}
|
||||
|
||||
void PlasmaApp::wmChanged()
|
||||
{
|
||||
// changing the window manager happens from the KCM, currently nothing to do when that happens
|
||||
}
|
||||
|
||||
void PlasmaApp::captureDesktop()
|
||||
{
|
||||
KToolInvocation::kdeinitExec("ksnapshot", QStringList() << "--fullscreen");
|
||||
|
@ -886,4 +1002,79 @@ void PlasmaApp::captureCurrentWindow()
|
|||
KToolInvocation::kdeinitExec("ksnapshot", QStringList() << "--current");
|
||||
}
|
||||
|
||||
void PlasmaApp::cleanup()
|
||||
{
|
||||
if (m_klauncher) {
|
||||
m_klauncher->call("cleanup");
|
||||
m_klauncher->deleteLater();
|
||||
m_klauncher = nullptr;
|
||||
}
|
||||
|
||||
if (m_wmproc && m_wmproc->state() != QProcess::NotRunning) {
|
||||
m_wmproc->kill();
|
||||
m_wmproc->waitForFinished();
|
||||
m_wmproc->deleteLater();
|
||||
m_wmproc = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PlasmaApp::nextPhase()
|
||||
{
|
||||
if (m_startupsuspend <= 0){
|
||||
switch (m_phase) {
|
||||
case 0: {
|
||||
static const QString kdedInterface = QString::fromLatin1("org.kde.kded");
|
||||
QDBusConnectionInterface* sessionInterface = QDBusConnection::sessionBus().interface();
|
||||
if (!sessionInterface->isServiceRegistered(kdedInterface)) {
|
||||
sessionInterface->startService(kdedInterface);
|
||||
}
|
||||
m_klauncher->call("autoStart", int(0));
|
||||
m_kcminit->call("runPhase1");
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
m_klauncher->call("autoStart", int(1));
|
||||
m_kcminit->call("runPhase2");
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
m_klauncher->call("autoStart", int(2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_phase++;
|
||||
}
|
||||
QTimer::singleShot(100, this, SLOT(nextPhase()));
|
||||
}
|
||||
|
||||
void PlasmaApp::defaultLogout()
|
||||
{
|
||||
logout(KWorkSpace::ShutdownConfirmYes, KWorkSpace::ShutdownTypeDefault);
|
||||
}
|
||||
|
||||
void PlasmaApp::logoutWithoutConfirmation()
|
||||
{
|
||||
logout(KWorkSpace::ShutdownConfirmNo, KWorkSpace::ShutdownTypeNone);
|
||||
}
|
||||
|
||||
void PlasmaApp::haltWithoutConfirmation()
|
||||
{
|
||||
logout(KWorkSpace::ShutdownConfirmNo, KWorkSpace::ShutdownTypeHalt);
|
||||
}
|
||||
|
||||
void PlasmaApp::rebootWithoutConfirmation()
|
||||
{
|
||||
logout(KWorkSpace::ShutdownConfirmNo, KWorkSpace::ShutdownTypeReboot);
|
||||
}
|
||||
|
||||
void PlasmaApp::doLogout()
|
||||
{
|
||||
cleanup();
|
||||
if (m_sdtype == KWorkSpace::ShutdownTypeDefault || m_sdtype == KWorkSpace::ShutdownTypeNone) {
|
||||
quit();
|
||||
} else {
|
||||
KDisplayManager().shutdown(m_sdtype);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_plasmaapp.cpp"
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
#ifndef PLASMA_APP_H
|
||||
#define PLASMA_APP_H
|
||||
|
||||
#include <QtCore/qtimer.h>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
#include <QTimer>
|
||||
#include <QWeakPointer>
|
||||
#include <QDBusInterface>
|
||||
#include <QProcess>
|
||||
|
||||
#include <KUniqueApplication>
|
||||
#include <Plasma/Plasma>
|
||||
|
@ -35,6 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include "desktoptracker.h"
|
||||
#include "kworkspace/kworkspace.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
@ -95,6 +98,11 @@ public Q_SLOTS:
|
|||
|
||||
QString supportInformation() const;
|
||||
|
||||
void suspendStartup(const QString &app);
|
||||
void resumeStartup(const QString &app);
|
||||
void logout(int confirm, int sdtype);
|
||||
void wmChanged();
|
||||
|
||||
protected:
|
||||
#ifdef Q_WS_X11
|
||||
PanelView *findPanelForTrigger(WId trigger) const;
|
||||
|
@ -123,6 +131,14 @@ private Q_SLOTS:
|
|||
void captureDesktop();
|
||||
void captureCurrentWindow();
|
||||
|
||||
void cleanup();
|
||||
void nextPhase();
|
||||
void defaultLogout();
|
||||
void logoutWithoutConfirmation();
|
||||
void haltWithoutConfirmation();
|
||||
void rebootWithoutConfirmation();
|
||||
void doLogout();
|
||||
|
||||
private:
|
||||
DesktopCorona *m_corona;
|
||||
PanelShadows *m_panelShadows;
|
||||
|
@ -138,6 +154,13 @@ private:
|
|||
QTimer m_desktopViewCreationTimer;
|
||||
int m_panelHidden;
|
||||
QHash<int, QWeakPointer<ControllerWindow> > m_widgetExplorers;
|
||||
int m_phase;
|
||||
QDBusInterface* m_klauncher;
|
||||
QDBusInterface* m_kcminit;
|
||||
QProcess* m_wmproc;
|
||||
int m_startupsuspend;
|
||||
bool m_dialogActive;
|
||||
KWorkSpace::ShutdownType m_sdtype;
|
||||
};
|
||||
|
||||
#endif // multiple inclusion guard
|
||||
|
|
|
@ -1,27 +1,21 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
Copyright 2007 Urs Wolfer <uwolfer @ kde.org>
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "shutdowndlg.h"
|
||||
#include "kworkspace/kdisplaymanager.h"
|
||||
|
@ -53,27 +47,6 @@ static bool kSwitchTitleEvent(QEvent *event)
|
|||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
void KSMShutdownFeedback::start()
|
||||
{
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
// Announce that the user MAY be logging out (Intended for the compositor)
|
||||
Display* dpy = QX11Info::display();
|
||||
Atom announce = XInternAtom(dpy, "_KDE_LOGGING_OUT", False);
|
||||
unsigned char dummy = 0;
|
||||
XChangeProperty(dpy, QX11Info::appRootWindow(), announce, announce, 8, PropModeReplace, &dummy, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void KSMShutdownFeedback::stop()
|
||||
{
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
// No longer logging out, announce (Intended for the compositor)
|
||||
Display* dpy = QX11Info::display();
|
||||
Atom announce = XInternAtom(dpy, "_KDE_LOGGING_OUT", False);
|
||||
XDeleteProperty(QX11Info::display(), QX11Info::appRootWindow(), announce);
|
||||
}
|
||||
}
|
||||
|
||||
KSMShutdownDlg::KSMShutdownDlg(QWidget* parent,
|
||||
bool maysd, bool choose, KWorkSpace::ShutdownType sdtype)
|
||||
: Plasma::Dialog(parent, Qt::Dialog | Qt::WindowStaysOnTopHint),
|
||||
|
@ -92,8 +65,13 @@ KSMShutdownDlg::KSMShutdownDlg(QWidget* parent,
|
|||
m_second(s_timeout),
|
||||
m_shutdownType(sdtype)
|
||||
{
|
||||
// make the screen gray
|
||||
KSMShutdownFeedback::start();
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
// Announce that the user MAY be logging out (Intended for the compositor)
|
||||
Display* dpy = QX11Info::display();
|
||||
Atom announce = XInternAtom(dpy, "_KDE_LOGGING_OUT", False);
|
||||
unsigned char dummy = 0;
|
||||
XChangeProperty(dpy, QX11Info::appRootWindow(), announce, announce, 8, PropModeReplace, &dummy, 1);
|
||||
}
|
||||
|
||||
m_scene = new QGraphicsScene(this);
|
||||
m_widget = new QGraphicsWidget();
|
||||
|
@ -247,8 +225,12 @@ KSMShutdownDlg::KSMShutdownDlg(QWidget* parent,
|
|||
|
||||
KSMShutdownDlg::~KSMShutdownDlg()
|
||||
{
|
||||
// make the screen become normal again
|
||||
KSMShutdownFeedback::stop();
|
||||
if (KWindowSystem::compositingActive()) {
|
||||
// No longer logging out, announce (Intended for the compositor)
|
||||
Display* dpy = QX11Info::display();
|
||||
Atom announce = XInternAtom(dpy, "_KDE_LOGGING_OUT", False);
|
||||
XDeleteProperty(QX11Info::display(), QX11Info::appRootWindow(), announce);
|
||||
}
|
||||
// delete m_widget;
|
||||
}
|
||||
|
||||
|
@ -363,10 +345,10 @@ bool KSMShutdownDlg::confirmShutdown(bool maysd, bool choose, KWorkSpace::Shutdo
|
|||
{
|
||||
KSMShutdownDlg* dialog = new KSMShutdownDlg(nullptr, maysd, choose, sdtype);
|
||||
|
||||
// NOTE: KWin logout effect expects class hint values to be ksmserver
|
||||
// NOTE: KWin logout effect expects class hint values to be plasma-desktop
|
||||
XClassHint classHint;
|
||||
classHint.res_name = const_cast<char*>("ksmserver");
|
||||
classHint.res_class = const_cast<char*>("ksmserver");
|
||||
classHint.res_name = const_cast<char*>("plasma-desktop");
|
||||
classHint.res_class = const_cast<char*>("plasma-desktop");
|
||||
XSetClassHint(QX11Info::display(), dialog->winId(), &classHint);
|
||||
|
||||
dialog->setWindowRole("logoutdialog");
|
|
@ -1,26 +1,21 @@
|
|||
/*****************************************************************
|
||||
ksmserver - the KDE session management server
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
Copyright 2000 Matthias Ettrich <ettrich@kde.org>
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License version 2, as published by the Free Software Foundation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef SHUTDOWNDLG_H
|
||||
#define SHUTDOWNDLG_H
|
||||
|
@ -35,15 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include <Plasma/Separator>
|
||||
#include <Plasma/IconWidget>
|
||||
#include <Plasma/PushButton>
|
||||
#include <kworkspace/kworkspace.h>
|
||||
|
||||
// The methods that make the desktop gray if compositor is active.
|
||||
class KSMShutdownFeedback
|
||||
{
|
||||
public:
|
||||
static void start();
|
||||
static void stop();
|
||||
};
|
||||
#include "kworkspace/kworkspace.h"
|
||||
|
||||
// The confirmation dialog
|
||||
class KSMShutdownDlg : public Plasma::Dialog
|
|
@ -13,19 +13,6 @@ fi
|
|||
# because we still need to do some cleanup.
|
||||
trap 'echo GOT SIGHUP' HUP
|
||||
|
||||
# Check if a KDE session already is running and whether it's possible to connect to X
|
||||
kcheckrunning
|
||||
kcheckrunning_result=$?
|
||||
if test $kcheckrunning_result -eq 0 ; then
|
||||
echo "KDE seems to be already running on this display."
|
||||
xmessage -geometry 500x100 "KDE seems to be already running on this display." > /dev/null 2>/dev/null
|
||||
exit 1
|
||||
elif test $kcheckrunning_result -eq 2 ; then
|
||||
echo "\$DISPLAY is not set or cannot connect to the X server."
|
||||
exit 1
|
||||
fi
|
||||
unset kcheckrunning_result
|
||||
|
||||
# Make sure that the KDE prefix is first in XDG_DATA_DIRS and that it's set at all.
|
||||
# The spec allows XDG_DATA_DIRS to be not set, but X session startup scripts tend
|
||||
# to set it to a list of paths *not* including the KDE prefix if it's not /usr or
|
||||
|
@ -44,7 +31,7 @@ test -n "$KDEHOME" && kdehome=`echo "$KDEHOME"|sed "s,^~/,$HOME/,"`
|
|||
|
||||
kcminputrc_mouse_cursortheme=`kreadconfig --file kcminputrc --group Mouse --key cursorTheme --default Oxygen_White`
|
||||
kcminputrc_mouse_cursorsize=`kreadconfig --file kcminputrc --group Mouse --key cursorSize`
|
||||
# XCursor mouse theme needs to be applied here to work even for kded or ksmserver
|
||||
# XCursor mouse theme needs to be applied here to work even for kded
|
||||
if test -n "$kcminputrc_mouse_cursortheme" -o -n "$kcminputrc_mouse_cursorsize" ; then
|
||||
@EXPORT_XCURSOR_PATH@
|
||||
|
||||
|
@ -131,24 +118,21 @@ kbuildsycoca4
|
|||
|
||||
# Start kcminit_startup
|
||||
kcminit_startup
|
||||
kcminit_result=$?
|
||||
if test $? -ne 0; then
|
||||
# Startup error
|
||||
echo 'startkde: Could not start kcminit_startup. Check your installation.' 1>&2
|
||||
xmessage -geometry 500x100 "Could not start kcminit_startup. Check your installation."
|
||||
echo "startkde: Could not start kcminit_startup ($kcminit_result). Check your installation." 1>&2
|
||||
xmessage -geometry 500x100 "Could not start kcminit_startup ($kcminit_result). Check your installation."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# finally, give the session control to the session manager
|
||||
# see kdebase/ksmserver for the description of the rest of the startup sequence
|
||||
# if the KDEWM environment variable has been set, then it will be used as KDE's
|
||||
# window manager instead of kwin.
|
||||
# if KDEWM is not set, ksmserver will ensure kwin is started.
|
||||
test -n "$KDEWM" && KDEWM="--windowmanager $KDEWM"
|
||||
ksmserver $KDEWM
|
||||
if test $? -ne 0; then
|
||||
# finally, give the session control to plasma-desktop
|
||||
plasma-desktop
|
||||
plasma_result=$?
|
||||
if test $plasma_result -ne 0; then
|
||||
# Startup error
|
||||
echo 'startkde: Could not start ksmserver. Check your installation.' 1>&2
|
||||
xmessage -geometry 500x100 "Could not start ksmserver. Check your installation."
|
||||
echo "startkde: Could not start plasma-desktop ($plasma_result). Check your installation." 1>&2
|
||||
xmessage -geometry 500x100 "Could not start plasma-desktop ($plasma_result). Check your installation."
|
||||
fi
|
||||
|
||||
echo 'startkde: Shutting down...' 1>&2
|
||||
|
|
Loading…
Add table
Reference in a new issue