mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 10:22:49 +00:00
kcontrol: convert desktoppaths, input and keyboard KCM initialization to autostart
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
f0232f48b2
commit
65eb546f63
31 changed files with 1130 additions and 1250 deletions
|
@ -272,8 +272,6 @@ add_subdirectory(kcontrol)
|
||||||
add_subdirectory(kmenuedit)
|
add_subdirectory(kmenuedit)
|
||||||
add_subdirectory(kinfocenter)
|
add_subdirectory(kinfocenter)
|
||||||
|
|
||||||
add_subdirectory(kcminit)
|
|
||||||
|
|
||||||
if (LightDM_FOUND)
|
if (LightDM_FOUND)
|
||||||
add_subdirectory(kgreeter)
|
add_subdirectory(kgreeter)
|
||||||
endif(LightDM_FOUND)
|
endif(LightDM_FOUND)
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
########### next target ###############
|
|
||||||
|
|
||||||
add_definitions(-DKDE_DEFAULT_DEBUG_AREA=90250)
|
|
||||||
|
|
||||||
add_executable(kcminit main.cpp)
|
|
||||||
|
|
||||||
target_link_libraries(kcminit
|
|
||||||
KDE4::kcmutils
|
|
||||||
KDE4::kdeui
|
|
||||||
${X11_LIBRARIES}
|
|
||||||
)
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS kcminit
|
|
||||||
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# write a cmake script file which creates the symlink
|
|
||||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/make_kcminit_startup_symlink.cmake
|
|
||||||
"EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E create_symlink kcminit \"\$ENV{DESTDIR}${KDE4_BIN_INSTALL_DIR}/kcminit_startup\")\n"
|
|
||||||
)
|
|
||||||
# and add it as post-install script for kcminit
|
|
||||||
set_target_properties(kcminit PROPERTIES
|
|
||||||
POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/make_kcminit_startup_symlink.cmake
|
|
||||||
)
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
$XGETTEXT *.cpp -o $podir/kcminit.pot
|
|
231
kcminit/main.cpp
231
kcminit/main.cpp
|
@ -1,231 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@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
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config-workspace.h>
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <QFile>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QLibrary>
|
|
||||||
#include <QtDBus/QtDBus>
|
|
||||||
|
|
||||||
#include <kapplication.h>
|
|
||||||
#include <kcmdlineargs.h>
|
|
||||||
#include <kaboutdata.h>
|
|
||||||
#include <kservice.h>
|
|
||||||
#include <kdebug.h>
|
|
||||||
#include <kconfig.h>
|
|
||||||
#include <kconfiggroup.h>
|
|
||||||
#include <klocale.h>
|
|
||||||
#include <kservicetypetrader.h>
|
|
||||||
#include <kglobalsettings.h>
|
|
||||||
|
|
||||||
#ifdef Q_WS_X11
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <QtGui/qx11info_x11.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int ready[ 2 ];
|
|
||||||
static bool startup = false;
|
|
||||||
|
|
||||||
static void sendReady()
|
|
||||||
{
|
|
||||||
if( ready[ 1 ] == -1 )
|
|
||||||
return;
|
|
||||||
char c = 0;
|
|
||||||
write( ready[ 1 ], &c, 1 );
|
|
||||||
close( ready[ 1 ] );
|
|
||||||
ready[ 1 ] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void waitForReady()
|
|
||||||
{
|
|
||||||
char c = 1;
|
|
||||||
close( ready[ 1 ] );
|
|
||||||
read( ready[ 0 ], &c, 1 );
|
|
||||||
close( ready[ 0 ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KCMInit::runModule(const QString &libName, KService::Ptr service)
|
|
||||||
{
|
|
||||||
QLibrary lib(libName);
|
|
||||||
if (lib.load()) {
|
|
||||||
QVariant tmp = service->property("X-KDE-Init-Symbol", QVariant::String);
|
|
||||||
QString kcminit;
|
|
||||||
if ( tmp.isValid() ) {
|
|
||||||
kcminit = tmp.toString();
|
|
||||||
if( !kcminit.startsWith( QLatin1String( "kcminit_" ) ) )
|
|
||||||
kcminit = "kcminit_" + kcminit;
|
|
||||||
} else {
|
|
||||||
kcminit = "kcminit_" + libName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the kcminit_ function
|
|
||||||
void *init = lib.resolve(kcminit.toUtf8());
|
|
||||||
if (init) {
|
|
||||||
// initialize the module
|
|
||||||
kDebug() << "Initializing " << libName << ": " << kcminit;
|
|
||||||
|
|
||||||
void (*func)() = (void(*)())init;
|
|
||||||
func();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
kDebug() << "Module" << libName << "does not actually have a kcminit function";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KCMInit::runModules( int phase )
|
|
||||||
{
|
|
||||||
for(KService::List::Iterator it = list.begin();
|
|
||||||
it != list.end();
|
|
||||||
++it) {
|
|
||||||
KService::Ptr service = (*it);
|
|
||||||
|
|
||||||
QString library = service->library();
|
|
||||||
if (library.isEmpty()) {
|
|
||||||
continue; // Skip
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant vphase = service->property("X-KDE-Init-Phase", QVariant::Int );
|
|
||||||
int libphase = 1;
|
|
||||||
if( vphase.isValid() )
|
|
||||||
libphase = vphase.toInt();
|
|
||||||
|
|
||||||
if( phase != -1 && libphase != phase )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// try to load the library
|
|
||||||
if (!alreadyInitialized.contains(library)) {
|
|
||||||
runModule(library, service);
|
|
||||||
alreadyInitialized.append(library);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KCMInit::KCMInit( KCmdLineArgs* args )
|
|
||||||
{
|
|
||||||
QDBusConnection::sessionBus().registerObject("/kcminit", this,
|
|
||||||
QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportScriptableSignals);
|
|
||||||
QString arg;
|
|
||||||
if (args->count() == 1) {
|
|
||||||
arg = args->arg(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args->isSet("list"))
|
|
||||||
{
|
|
||||||
list = KServiceTypeTrader::self()->query( "KCModuleInit" );
|
|
||||||
|
|
||||||
for(KService::List::Iterator it = list.begin();
|
|
||||||
it != list.end();
|
|
||||||
++it)
|
|
||||||
{
|
|
||||||
KService::Ptr service = (*it);
|
|
||||||
if (service->library().isEmpty())
|
|
||||||
continue; // Skip
|
|
||||||
printf("%s\n", QFile::encodeName(service->desktopEntryName()).data());
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!arg.isEmpty()) {
|
|
||||||
|
|
||||||
QString module = arg;
|
|
||||||
if (!module.endsWith(".desktop"))
|
|
||||||
module += ".desktop";
|
|
||||||
|
|
||||||
KService::Ptr serv = KService::serviceByStorageId( module );
|
|
||||||
if ( !serv || serv->library().isEmpty() ) {
|
|
||||||
kError() << i18n("Module %1 not found", module);
|
|
||||||
return;
|
|
||||||
} else
|
|
||||||
list.append(serv);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// locate the desktop files
|
|
||||||
list = KServiceTypeTrader::self()->query( "KCModuleInit" );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if( startup )
|
|
||||||
{
|
|
||||||
runModules( 0 );
|
|
||||||
sendReady();
|
|
||||||
QTimer::singleShot( 300 * 1000, qApp, SLOT(quit())); // just in case
|
|
||||||
qApp->exec(); // wait for runPhase1() and runPhase2()
|
|
||||||
}
|
|
||||||
else
|
|
||||||
runModules( -1 ); // all phases
|
|
||||||
}
|
|
||||||
|
|
||||||
KCMInit::~KCMInit()
|
|
||||||
{
|
|
||||||
sendReady();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KCMInit::runPhase1()
|
|
||||||
{
|
|
||||||
runModules( 1 );
|
|
||||||
emit phase1Done();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KCMInit::runPhase2()
|
|
||||||
{
|
|
||||||
runModules( 2 );
|
|
||||||
emit phase2Done();
|
|
||||||
qApp->exit( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
// during KDE startup only important kcm's are started very early in the login process,
|
|
||||||
// the rest is delayed, so fork and make parent return after the initial phase
|
|
||||||
pipe( ready );
|
|
||||||
if( fork() != 0 )
|
|
||||||
{
|
|
||||||
waitForReady();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
close( ready[ 0 ] );
|
|
||||||
|
|
||||||
startup = ( strcmp( argv[ 0 ], "kcminit_startup" ) == 0 ); // started from startkde?
|
|
||||||
KAboutData aboutData( "kcminit", "kcminit", ki18n("KCMInit"),
|
|
||||||
"",
|
|
||||||
ki18n("KCMInit - runs startup initialization for Control Modules."));
|
|
||||||
|
|
||||||
KCmdLineArgs::init(argc, argv, &aboutData);
|
|
||||||
|
|
||||||
KCmdLineOptions options;
|
|
||||||
options.add("list", ki18n("List modules that are run at startup"));
|
|
||||||
options.add("+module", ki18n("Configuration module to run"));
|
|
||||||
KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
|
|
||||||
|
|
||||||
KApplication app;
|
|
||||||
QDBusConnection::sessionBus().interface()->registerService( "org.kde.kcminit",
|
|
||||||
QDBusConnectionInterface::DontQueueService );
|
|
||||||
KCMInit kcminit( KCmdLineArgs::parsedArgs());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_main.cpp"
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@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
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MAIN_H
|
|
||||||
#define MAIN_H
|
|
||||||
|
|
||||||
#include <kservice.h>
|
|
||||||
|
|
||||||
class KCmdLineArgs;
|
|
||||||
|
|
||||||
class KCMInit : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_CLASSINFO("D-Bus Interface", "org.kde.KCMInit")
|
|
||||||
public Q_SLOTS: //dbus
|
|
||||||
Q_SCRIPTABLE void runPhase1();
|
|
||||||
Q_SCRIPTABLE void runPhase2();
|
|
||||||
Q_SIGNALS: //dbus signal
|
|
||||||
Q_SCRIPTABLE void phase1Done();
|
|
||||||
Q_SCRIPTABLE void phase2Done();
|
|
||||||
public:
|
|
||||||
KCMInit( KCmdLineArgs* args );
|
|
||||||
virtual ~KCMInit();
|
|
||||||
private:
|
|
||||||
bool runModule(const QString &libName, KService::Ptr service);
|
|
||||||
void runModules( int phase );
|
|
||||||
KService::List list;
|
|
||||||
QStringList alreadyInitialized;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MAIN_H
|
|
|
@ -1,5 +1,4 @@
|
||||||
set(kcm_desktoppaths_PART_SRCS
|
set(kcm_desktoppaths_PART_SRCS
|
||||||
globalpaths.cpp
|
|
||||||
kcmdesktoppaths.cpp
|
kcmdesktoppaths.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,3 +25,20 @@ install(
|
||||||
data/Home.desktop
|
data/Home.desktop
|
||||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/kcm_desktoppaths
|
DESTINATION ${KDE4_DATA_INSTALL_DIR}/kcm_desktoppaths
|
||||||
)
|
)
|
||||||
|
|
||||||
|
########### next target ###############
|
||||||
|
|
||||||
|
add_executable(kdesktoppaths kdesktoppaths.cpp)
|
||||||
|
target_link_libraries(kdesktoppaths
|
||||||
|
KDE4::kdecore
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS kdesktoppaths
|
||||||
|
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES kdesktoppaths.desktop
|
||||||
|
DESTINATION ${KDE4_AUTOSTART_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Type=Service
|
Type=Service
|
||||||
X-KDE-ServiceTypes=KCModule,KCModuleInit
|
X-KDE-ServiceTypes=KCModule
|
||||||
X-DocPath=kcontrol/paths/index.html
|
X-DocPath=kcontrol/paths/index.html
|
||||||
Icon=system-file-manager
|
Icon=system-file-manager
|
||||||
Exec=kcmshell4 desktoppath
|
Exec=kcmshell4 desktoppath
|
||||||
|
|
||||||
X-KDE-Library=kcm_desktoppaths
|
X-KDE-Library=kcm_desktoppaths
|
||||||
X-KDE-Init-Symbol=kcminit_desktoppaths
|
|
||||||
X-KDE-PluginKeyword=dpath
|
X-KDE-PluginKeyword=dpath
|
||||||
X-KDE-ParentApp=kcontrol
|
X-KDE-ParentApp=kcontrol
|
||||||
X-KDE-System-Settings-Parent-Category=account-details
|
X-KDE-System-Settings-Parent-Category=account-details
|
||||||
|
|
|
@ -1,367 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Martin R. Jones 1996
|
|
||||||
* Copyright (c) Bernd Wuebben 1998
|
|
||||||
* Copyright (c) Christian Tibirna 1998
|
|
||||||
* Copyright 1998-2007 David Faure <faure@kde.org>
|
|
||||||
* Copyright (c) 2010 Matthias Fuchs <mat69@gmx.net>
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// "Desktop Options" Tab for KDesktop configuration
|
|
||||||
//
|
|
||||||
// (c) Martin R. Jones 1996
|
|
||||||
// (c) Bernd Wuebben 1998
|
|
||||||
//
|
|
||||||
// Layouts
|
|
||||||
// (c) Christian Tibirna 1998
|
|
||||||
// Port to KControl, split from Misc Tab, Port to KControl2
|
|
||||||
// (c) David Faure 1998
|
|
||||||
// Desktop menus, paths
|
|
||||||
// (c) David Faure 2000
|
|
||||||
|
|
||||||
|
|
||||||
// Own
|
|
||||||
#include "globalpaths.h"
|
|
||||||
|
|
||||||
// Qt
|
|
||||||
#include <QtGui/QCheckBox>
|
|
||||||
#include <QtGui/QComboBox>
|
|
||||||
#include <QtGui/QLabel>
|
|
||||||
#include <QtGui/QLayout>
|
|
||||||
#include <QtGui/QFormLayout>
|
|
||||||
#include <QtGui/QDesktopWidget>
|
|
||||||
#include <QtGui/QApplication>
|
|
||||||
#include <QtDBus/QtDBus>
|
|
||||||
|
|
||||||
// KDE
|
|
||||||
#include <kconfiggroup.h>
|
|
||||||
#include <kdebug.h>
|
|
||||||
#include <kfileitem.h>
|
|
||||||
#include <kglobalsettings.h>
|
|
||||||
#include <kio/copyjob.h>
|
|
||||||
#include <kio/deletejob.h>
|
|
||||||
#include <kio/job.h>
|
|
||||||
#include <kio/jobuidelegate.h>
|
|
||||||
#include <klocale.h>
|
|
||||||
#include <kmessagebox.h>
|
|
||||||
#include <kmimetype.h>
|
|
||||||
#include <kstandarddirs.h>
|
|
||||||
#include <kurlrequester.h>
|
|
||||||
|
|
||||||
#include "kcmdesktoppaths.h"
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DesktopPathConfig::DesktopPathConfig(QWidget *parent, const QVariantList &)
|
|
||||||
: KCModule( KcmDesktopPaths::componentData(), parent )
|
|
||||||
{
|
|
||||||
QFormLayout *lay = new QFormLayout(this);
|
|
||||||
lay->setMargin(0);
|
|
||||||
|
|
||||||
setQuickHelp( i18n("<h1>Paths</h1>\n"
|
|
||||||
"This module allows you to choose where in the filesystem the "
|
|
||||||
"files on your desktop should be stored.\n"
|
|
||||||
"Use the \"Whats This?\" (Shift+F1) to get help on specific options."));
|
|
||||||
|
|
||||||
urDesktop = addRow(lay, i18n("Desktop path:"),
|
|
||||||
i18n("This folder contains all the files"
|
|
||||||
" which you see on your desktop. You can change the location of this"
|
|
||||||
" folder if you want to, and the contents will move automatically"
|
|
||||||
" to the new location as well."));
|
|
||||||
|
|
||||||
urDocument = addRow(lay, i18n("Documents path:"),
|
|
||||||
i18n("This folder will be used by default to "
|
|
||||||
"load or save documents from or to."));
|
|
||||||
|
|
||||||
urDownload = addRow(lay, i18n("Downloads path:"),
|
|
||||||
i18n("This folder will be used by default to "
|
|
||||||
"save your downloaded items."));
|
|
||||||
|
|
||||||
urMovie = addRow(lay, i18n("Movies path:"),
|
|
||||||
i18n("This folder will be used by default to "
|
|
||||||
"load or save movies from or to."));
|
|
||||||
|
|
||||||
urPicture = addRow(lay, i18n("Pictures path:"),
|
|
||||||
i18n("This folder will be used by default to "
|
|
||||||
"load or save pictures from or to."));
|
|
||||||
|
|
||||||
urMusic = addRow(lay, i18n("Music path:"),
|
|
||||||
i18n("This folder will be used by default to "
|
|
||||||
"load or save music from or to."));
|
|
||||||
}
|
|
||||||
|
|
||||||
KUrlRequester* DesktopPathConfig::addRow(QFormLayout *lay, const QString& label, const QString& whatsThis)
|
|
||||||
{
|
|
||||||
KUrlRequester* ur = new KUrlRequester(this);
|
|
||||||
ur->setMode(KFile::Directory | KFile::LocalOnly);
|
|
||||||
lay->addRow(label, ur);
|
|
||||||
connect(ur, SIGNAL(textChanged(QString)), this, SLOT(changed()));
|
|
||||||
lay->labelForField(ur)->setWhatsThis(whatsThis);
|
|
||||||
ur->setWhatsThis(whatsThis);
|
|
||||||
return ur;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopPathConfig::load()
|
|
||||||
{
|
|
||||||
// Desktop Paths
|
|
||||||
urDesktop->setUrl( KGlobalSettings::desktopPath() );
|
|
||||||
urDocument->setUrl( KGlobalSettings::documentPath() );
|
|
||||||
urDownload->setUrl( KGlobalSettings::downloadPath() );
|
|
||||||
urMovie->setUrl( KGlobalSettings::videosPath() );
|
|
||||||
urPicture->setUrl( KGlobalSettings::picturesPath() );
|
|
||||||
urMusic->setUrl( KGlobalSettings::musicPath() );
|
|
||||||
emit changed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopPathConfig::defaults()
|
|
||||||
{
|
|
||||||
// Desktop Paths - keep defaults in sync with kglobalsettings.cpp
|
|
||||||
urDesktop->setUrl( QString(QDir::homePath() + "/Desktop") );
|
|
||||||
urDocument->setUrl( QString(QDir::homePath() + "/Documents") );
|
|
||||||
urDownload->setUrl( QString(QDir::homePath() + "/Downloads") );
|
|
||||||
urMovie->setUrl( QString(QDir::homePath() + "/Movies") );
|
|
||||||
urPicture->setUrl( QString(QDir::homePath() + "/Pictures") );
|
|
||||||
urMusic->setUrl( QString(QDir::homePath() + "/Music") );
|
|
||||||
}
|
|
||||||
|
|
||||||
// the following method is copied from kdelibs/kdecore/config/kconfiggroup.cpp
|
|
||||||
static bool cleanHomeDirPath( QString &path, const QString &homeDir )
|
|
||||||
{
|
|
||||||
if (!path.startsWith(homeDir))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int len = homeDir.length();
|
|
||||||
// replace by "$HOME" if possible
|
|
||||||
if (len && (path.length() == len || path[len] == '/')) {
|
|
||||||
path.replace(0, len, QString::fromLatin1("$HOME"));
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO this functionality is duplicated in libkonq - keep it only there and export
|
|
||||||
|
|
||||||
static QString translatePath( QString path ) // krazy:exclude=passbyvalue
|
|
||||||
{
|
|
||||||
// keep only one single '/' at the beginning - needed for cleanHomeDirPath()
|
|
||||||
while (path[0] == '/' && path[1] == '/')
|
|
||||||
path.remove(0,1);
|
|
||||||
|
|
||||||
// we probably should escape any $ ` and \ characters that may occur in the path, but the Qt code that reads back
|
|
||||||
// the file doesn't unescape them so not much point in doing so
|
|
||||||
|
|
||||||
// All of the 3 following functions to return the user's home directory
|
|
||||||
// can return different paths. We have to test all them.
|
|
||||||
const QString homeDir0 = QFile::decodeName(qgetenv("HOME"));
|
|
||||||
const QString homeDir1 = QDir::homePath();
|
|
||||||
const QString homeDir2 = QDir(homeDir1).canonicalPath();
|
|
||||||
if (cleanHomeDirPath(path, homeDir0) ||
|
|
||||||
cleanHomeDirPath(path, homeDir1) ||
|
|
||||||
cleanHomeDirPath(path, homeDir2) ) {
|
|
||||||
// kDebug() << "Path was replaced\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopPathConfig::save()
|
|
||||||
{
|
|
||||||
KSharedConfig::Ptr config = KGlobal::config();
|
|
||||||
KConfigGroup configGroup( config, "Paths" );
|
|
||||||
|
|
||||||
bool pathChanged = false;
|
|
||||||
|
|
||||||
KUrl desktopURL( KGlobalSettings::desktopPath() );
|
|
||||||
|
|
||||||
if ( !urDesktop->url().equals( desktopURL, KUrl::RemoveTrailingSlash ) )
|
|
||||||
{
|
|
||||||
// Test which other paths were inside this one (as it is by default)
|
|
||||||
// and for each, test where it should go.
|
|
||||||
// * Inside destination -> let them be moved with the desktop (but adjust name if necessary)
|
|
||||||
// * Not inside destination -> move first
|
|
||||||
// !!!
|
|
||||||
kDebug() << "desktopURL=" << desktopURL;
|
|
||||||
QString urlDesktop = urDesktop->url().toLocalFile();
|
|
||||||
if ( !urlDesktop.endsWith('/'))
|
|
||||||
urlDesktop+='/';
|
|
||||||
|
|
||||||
if ( moveDir( KUrl( KGlobalSettings::desktopPath() ), KUrl( urlDesktop ), i18n("Desktop") ) )
|
|
||||||
{
|
|
||||||
//save in XDG path
|
|
||||||
const QString userDirsFile(KGlobal::dirs()->localxdgconfdir() + QLatin1String("user-dirs.dirs"));
|
|
||||||
KConfig xdgUserConf( userDirsFile, KConfig::SimpleConfig );
|
|
||||||
KConfigGroup g( &xdgUserConf, "" );
|
|
||||||
g.writeEntry( "XDG_DESKTOP_DIR", QString("\"" + translatePath( urlDesktop ) + "\"") );
|
|
||||||
pathChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config->sync();
|
|
||||||
|
|
||||||
if (xdgSavePath(urDocument, KGlobalSettings::documentPath(), "XDG_DOCUMENTS_DIR", i18n("Documents")))
|
|
||||||
pathChanged = true;
|
|
||||||
|
|
||||||
if (xdgSavePath(urDownload, KGlobalSettings::downloadPath(), "XDG_DOWNLOAD_DIR", i18n("Downloads")))
|
|
||||||
pathChanged = true;
|
|
||||||
|
|
||||||
if (xdgSavePath(urMovie, KGlobalSettings::videosPath(), "XDG_VIDEOS_DIR", i18n("Movies")))
|
|
||||||
pathChanged = true;
|
|
||||||
|
|
||||||
if (xdgSavePath(urPicture, KGlobalSettings::picturesPath(), "XDG_PICTURES_DIR", i18n("Pictures")))
|
|
||||||
pathChanged = true;
|
|
||||||
|
|
||||||
if (xdgSavePath(urMusic, KGlobalSettings::musicPath(), "XDG_MUSIC_DIR", i18n("Music")))
|
|
||||||
pathChanged = true;
|
|
||||||
|
|
||||||
if (pathChanged) {
|
|
||||||
kDebug() << "sending message SettingsChanged";
|
|
||||||
KGlobalSettings::self()->emitChange(KGlobalSettings::PathsChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DesktopPathConfig::xdgSavePath(KUrlRequester* ur, const KUrl& currentUrl, const char* xdgKey, const QString& type)
|
|
||||||
{
|
|
||||||
KUrl newUrl = ur->url();
|
|
||||||
//url might be empty, use QDir::homePath (the default for xdg) then
|
|
||||||
if (!newUrl.isValid()) {
|
|
||||||
newUrl = KUrl(QDir::homePath());
|
|
||||||
}
|
|
||||||
if (!newUrl.equals(currentUrl, KUrl::RemoveTrailingSlash)) {
|
|
||||||
const QString path = newUrl.toLocalFile();
|
|
||||||
if (!QDir(path).exists()) {
|
|
||||||
// Check permissions
|
|
||||||
if (KStandardDirs::makeDir(path)) {
|
|
||||||
QDir().rmdir(path); // rmdir again, so that we get a fast rename
|
|
||||||
} else {
|
|
||||||
KMessageBox::sorry(this, KIO::buildErrorString(KIO::ERR_COULD_NOT_MKDIR, path));
|
|
||||||
ur->setUrl(currentUrl); // revert
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (moveDir(currentUrl, newUrl, type)) {
|
|
||||||
//save in XDG user-dirs.dirs config file, this is where KGlobalSettings/QStandardPaths reads from.
|
|
||||||
const QString userDirsFile(KGlobal::dirs()->localxdgconfdir() + QLatin1String("user-dirs.dirs"));
|
|
||||||
KConfig xdgUserConf(userDirsFile, KConfig::SimpleConfig);
|
|
||||||
KConfigGroup g(&xdgUserConf, "");
|
|
||||||
g.writeEntry(xdgKey, QString("\"" + translatePath(path) + "\""));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DesktopPathConfig::moveDir( const KUrl & src, const KUrl & dest, const QString & type )
|
|
||||||
{
|
|
||||||
if (!src.isLocalFile() || !dest.isLocalFile())
|
|
||||||
return true;
|
|
||||||
if (!QDir(src.toLocalFile()).exists())
|
|
||||||
return true;
|
|
||||||
// Do not move $HOME! #193057
|
|
||||||
const QString translatedPath = translatePath(src.toLocalFile());
|
|
||||||
if (translatedPath == "$HOME" || translatedPath == "$HOME/") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ok = true;
|
|
||||||
|
|
||||||
QString question;
|
|
||||||
KGuiItem yesItem;
|
|
||||||
KGuiItem noItem;
|
|
||||||
const bool destExists = QDir(dest.toLocalFile()).exists();
|
|
||||||
if (destExists) {
|
|
||||||
// TODO: check if the src dir is empty? Nothing to move, then...
|
|
||||||
question = i18n("The path for '%1' has been changed.\nDo you want the files to be moved from '%2' to '%3'?",
|
|
||||||
type, src.toLocalFile(),
|
|
||||||
dest.toLocalFile());
|
|
||||||
yesItem = KGuiItem(i18nc("Move files from old to new place", "Move"));
|
|
||||||
noItem = KGuiItem(i18nc("Use the new directory but do not move files", "Do not Move"));
|
|
||||||
} else {
|
|
||||||
question = i18n("The path for '%1' has been changed.\nDo you want to move the directory '%2' to '%3'?",
|
|
||||||
type, src.toLocalFile(),
|
|
||||||
dest.toLocalFile());
|
|
||||||
yesItem = KGuiItem(i18nc("Move the directory", "Move"));
|
|
||||||
noItem = KGuiItem(i18nc("Use the new directory but do not move anything", "Do not Move"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask for confirmation before moving the files
|
|
||||||
if (KMessageBox::questionYesNo(this, question, i18n("Confirmation Required"),
|
|
||||||
yesItem, noItem)
|
|
||||||
== KMessageBox::Yes )
|
|
||||||
{
|
|
||||||
if (destExists) {
|
|
||||||
// Destination already exists -- should always be the case, for most types,
|
|
||||||
// but maybe not for the complex autostart case (to be checked...)
|
|
||||||
m_copyToDest = dest;
|
|
||||||
m_copyFromSrc = src;
|
|
||||||
KIO::ListJob* job = KIO::listDir( src );
|
|
||||||
job->setAutoDelete(false); // see <noautodelete> below
|
|
||||||
job->ui()->setWindow(this);
|
|
||||||
job->ui()->setAutoErrorHandlingEnabled(true);
|
|
||||||
connect(job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
|
|
||||||
this, SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList)));
|
|
||||||
// slotEntries will move every file/subdir individually into the dest
|
|
||||||
job->exec();
|
|
||||||
if (m_ok) {
|
|
||||||
QDir().rmdir(src.toLocalFile()); // hopefully it's empty by now
|
|
||||||
}
|
|
||||||
delete job;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
kDebug() << "Direct move from" << src << "to" << dest;
|
|
||||||
KIO::Job * job = KIO::move( src, dest );
|
|
||||||
job->ui()->setWindow(this);
|
|
||||||
connect(job, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
|
|
||||||
job->exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kDebug() << "DesktopPathConfig::slotResult returning " << m_ok;
|
|
||||||
return m_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopPathConfig::slotEntries(KIO::Job*, const KIO::UDSEntryList& list)
|
|
||||||
{
|
|
||||||
QListIterator<KIO::UDSEntry> it(list);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
KFileItem file(it.next(), m_copyFromSrc, true, true);
|
|
||||||
kDebug() << file.url();
|
|
||||||
if (file.url() == m_copyFromSrc || file.url().fileName() == "..") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
KIO::Job * moveJob = KIO::move(file.url(), m_copyToDest);
|
|
||||||
moveJob->ui()->setWindow(this);
|
|
||||||
connect(moveJob, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
|
|
||||||
moveJob->exec(); // sub-event loop here. <noautodelete>: the main job is not autodeleted because it would be deleted here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DesktopPathConfig::slotResult( KJob * job )
|
|
||||||
{
|
|
||||||
if (job->error()) {
|
|
||||||
if ( job->error() != KIO::ERR_DOES_NOT_EXIST )
|
|
||||||
m_ok = false;
|
|
||||||
|
|
||||||
// If the source doesn't exist, no wonder we couldn't move the dir.
|
|
||||||
// In that case, trust the user and set the new setting in any case.
|
|
||||||
|
|
||||||
static_cast<KIO::Job*>(job)->ui()->showErrorMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_globalpaths.cpp"
|
|
|
@ -1,83 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Martin R. Jones 1996
|
|
||||||
* Copyright 1998-2007 David Faure <faure@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
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Summarized history:
|
|
||||||
//
|
|
||||||
// "Desktop Icons Options" Tab for KDesktop configuration
|
|
||||||
// Martin Jones
|
|
||||||
//
|
|
||||||
// Port to KControl, split from "Misc" Tab, Port to KControl2
|
|
||||||
// (c) David Faure 1998
|
|
||||||
// Desktop menus, paths
|
|
||||||
// (c) David Faure 2000
|
|
||||||
|
|
||||||
#ifndef GLOBALPATHS_H
|
|
||||||
#define GLOBALPATHS_H
|
|
||||||
|
|
||||||
#include <kcmodule.h>
|
|
||||||
#include <kio/global.h>
|
|
||||||
#include <kio/udsentry.h>
|
|
||||||
#include <kurl.h>
|
|
||||||
|
|
||||||
#include <QFormLayout>
|
|
||||||
class KJob;
|
|
||||||
class KUrlRequester;
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
namespace KIO { class Job; }
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// The "Path" Tab contains :
|
|
||||||
// The paths for Desktop, Autostart and Documents
|
|
||||||
|
|
||||||
class DesktopPathConfig : public KCModule
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
DesktopPathConfig( QWidget *parent, const QVariantList &args );
|
|
||||||
virtual void load();
|
|
||||||
virtual void save();
|
|
||||||
virtual void defaults();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void slotEntries( KIO::Job * job, const KIO::UDSEntryList& list);
|
|
||||||
|
|
||||||
private:
|
|
||||||
KUrlRequester* addRow(QFormLayout *lay, const QString& label, const QString& whatsThis);
|
|
||||||
bool xdgSavePath(KUrlRequester* ur, const KUrl& currentUrl, const char* xdgKey, const QString& type);
|
|
||||||
|
|
||||||
// Desktop Paths
|
|
||||||
KUrlRequester *urDesktop;
|
|
||||||
KUrlRequester *urDocument;
|
|
||||||
KUrlRequester *urDownload;
|
|
||||||
KUrlRequester *urMovie;
|
|
||||||
KUrlRequester *urPicture;
|
|
||||||
KUrlRequester *urMusic;
|
|
||||||
|
|
||||||
bool moveDir( const KUrl & src, const KUrl & dest, const QString & type );
|
|
||||||
bool m_ok;
|
|
||||||
KUrl m_copyToDest; // used when the destination directory already exists
|
|
||||||
KUrl m_copyFromSrc;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void slotResult( KJob * job );
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,71 +1,373 @@
|
||||||
/* This file is part of the KDE project
|
/**
|
||||||
Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>
|
* Copyright (c) Martin R. Jones 1996
|
||||||
|
* Copyright (c) Bernd Wuebben 1998
|
||||||
|
* Copyright (c) Christian Tibirna 1998
|
||||||
|
* Copyright 1998-2007 David Faure <faure@kde.org>
|
||||||
|
* Copyright (c) 2010 Matthias Fuchs <mat69@gmx.net>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
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.
|
// "Desktop Options" Tab for KDesktop configuration
|
||||||
|
//
|
||||||
|
// (c) Martin R. Jones 1996
|
||||||
|
// (c) Bernd Wuebben 1998
|
||||||
|
//
|
||||||
|
// Layouts
|
||||||
|
// (c) Christian Tibirna 1998
|
||||||
|
// Port to KControl, split from Misc Tab, Port to KControl2
|
||||||
|
// (c) David Faure 1998
|
||||||
|
// Desktop menus, paths
|
||||||
|
// (c) David Faure 2000
|
||||||
|
|
||||||
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
|
// Own
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
#include "kcmdesktoppaths.h"
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
*/
|
// Katie
|
||||||
|
#include <QtGui/QCheckBox>
|
||||||
|
#include <QtGui/QComboBox>
|
||||||
|
#include <QtGui/QLabel>
|
||||||
|
#include <QtGui/QLayout>
|
||||||
|
#include <QtGui/QFormLayout>
|
||||||
|
#include <QtGui/QDesktopWidget>
|
||||||
|
#include <QtGui/QApplication>
|
||||||
|
#include <QtDBus/QtDBus>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
#include <kconfiggroup.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
#include <kfileitem.h>
|
||||||
|
#include <kglobalsettings.h>
|
||||||
|
#include <kio/copyjob.h>
|
||||||
|
#include <kio/deletejob.h>
|
||||||
|
#include <kio/job.h>
|
||||||
|
#include <kio/jobuidelegate.h>
|
||||||
|
#include <klocale.h>
|
||||||
|
#include <kmessagebox.h>
|
||||||
|
#include <kmimetype.h>
|
||||||
|
#include <kstandarddirs.h>
|
||||||
|
#include <kurlrequester.h>
|
||||||
|
#include <kpluginfactory.h>
|
||||||
|
#include <kpluginloader.h>
|
||||||
|
|
||||||
#include "kcmdesktoppaths.h"
|
#include "kcmdesktoppaths.h"
|
||||||
#include "globalpaths.h"
|
|
||||||
|
|
||||||
#include <QStandardPaths>
|
//-----------------------------------------------------------------------------
|
||||||
#include <QDir>
|
|
||||||
#include <KStandardDirs>
|
|
||||||
#include <KPluginFactory>
|
|
||||||
#include <KPluginLoader>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
|
K_PLUGIN_FACTORY_DECLARATION(KcmDesktopPaths)
|
||||||
K_PLUGIN_FACTORY_DEFINITION(KcmDesktopPaths, registerPlugin<DesktopPathConfig>("dpath");)
|
K_PLUGIN_FACTORY_DEFINITION(KcmDesktopPaths, registerPlugin<DesktopPathConfig>("dpath");)
|
||||||
K_EXPORT_PLUGIN(KcmDesktopPaths("kcm_desktoppaths"))
|
K_EXPORT_PLUGIN(KcmDesktopPaths("kcm_desktoppaths"))
|
||||||
|
|
||||||
extern "C"
|
DesktopPathConfig::DesktopPathConfig(QWidget *parent, const QVariantList &)
|
||||||
|
: KCModule( KcmDesktopPaths::componentData(), parent )
|
||||||
{
|
{
|
||||||
Q_DECL_EXPORT void kcminit_desktoppaths()
|
QFormLayout *lay = new QFormLayout(this);
|
||||||
|
lay->setMargin(0);
|
||||||
|
|
||||||
|
setQuickHelp( i18n("<h1>Paths</h1>\n"
|
||||||
|
"This module allows you to choose where in the filesystem the "
|
||||||
|
"files on your desktop should be stored.\n"
|
||||||
|
"Use the \"Whats This?\" (Shift+F1) to get help on specific options."));
|
||||||
|
|
||||||
|
urDesktop = addRow(lay, i18n("Desktop path:"),
|
||||||
|
i18n("This folder contains all the files"
|
||||||
|
" which you see on your desktop. You can change the location of this"
|
||||||
|
" folder if you want to, and the contents will move automatically"
|
||||||
|
" to the new location as well."));
|
||||||
|
|
||||||
|
urDocument = addRow(lay, i18n("Documents path:"),
|
||||||
|
i18n("This folder will be used by default to "
|
||||||
|
"load or save documents from or to."));
|
||||||
|
|
||||||
|
urDownload = addRow(lay, i18n("Downloads path:"),
|
||||||
|
i18n("This folder will be used by default to "
|
||||||
|
"save your downloaded items."));
|
||||||
|
|
||||||
|
urMovie = addRow(lay, i18n("Movies path:"),
|
||||||
|
i18n("This folder will be used by default to "
|
||||||
|
"load or save movies from or to."));
|
||||||
|
|
||||||
|
urPicture = addRow(lay, i18n("Pictures path:"),
|
||||||
|
i18n("This folder will be used by default to "
|
||||||
|
"load or save pictures from or to."));
|
||||||
|
|
||||||
|
urMusic = addRow(lay, i18n("Music path:"),
|
||||||
|
i18n("This folder will be used by default to "
|
||||||
|
"load or save music from or to."));
|
||||||
|
}
|
||||||
|
|
||||||
|
KUrlRequester* DesktopPathConfig::addRow(QFormLayout *lay, const QString& label, const QString& whatsThis)
|
||||||
|
{
|
||||||
|
KUrlRequester* ur = new KUrlRequester(this);
|
||||||
|
ur->setMode(KFile::Directory | KFile::LocalOnly);
|
||||||
|
lay->addRow(label, ur);
|
||||||
|
connect(ur, SIGNAL(textChanged(QString)), this, SLOT(changed()));
|
||||||
|
lay->labelForField(ur)->setWhatsThis(whatsThis);
|
||||||
|
ur->setWhatsThis(whatsThis);
|
||||||
|
return ur;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPathConfig::load()
|
||||||
|
{
|
||||||
|
// Desktop Paths
|
||||||
|
urDesktop->setUrl( KGlobalSettings::desktopPath() );
|
||||||
|
urDocument->setUrl( KGlobalSettings::documentPath() );
|
||||||
|
urDownload->setUrl( KGlobalSettings::downloadPath() );
|
||||||
|
urMovie->setUrl( KGlobalSettings::videosPath() );
|
||||||
|
urPicture->setUrl( KGlobalSettings::picturesPath() );
|
||||||
|
urMusic->setUrl( KGlobalSettings::musicPath() );
|
||||||
|
emit changed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPathConfig::defaults()
|
||||||
|
{
|
||||||
|
// Desktop Paths - keep defaults in sync with kglobalsettings.cpp
|
||||||
|
urDesktop->setUrl( QString(QDir::homePath() + "/Desktop") );
|
||||||
|
urDocument->setUrl( QString(QDir::homePath() + "/Documents") );
|
||||||
|
urDownload->setUrl( QString(QDir::homePath() + "/Downloads") );
|
||||||
|
urMovie->setUrl( QString(QDir::homePath() + "/Movies") );
|
||||||
|
urPicture->setUrl( QString(QDir::homePath() + "/Pictures") );
|
||||||
|
urMusic->setUrl( QString(QDir::homePath() + "/Music") );
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following method is copied from kdelibs/kdecore/config/kconfiggroup.cpp
|
||||||
|
static bool cleanHomeDirPath( QString &path, const QString &homeDir )
|
||||||
|
{
|
||||||
|
if (!path.startsWith(homeDir))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int len = homeDir.length();
|
||||||
|
// replace by "$HOME" if possible
|
||||||
|
if (len && (path.length() == len || path[len] == '/')) {
|
||||||
|
path.replace(0, len, QString::fromLatin1("$HOME"));
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this functionality is duplicated in libkonq - keep it only there and export
|
||||||
|
|
||||||
|
static QString translatePath( QString path ) // krazy:exclude=passbyvalue
|
||||||
|
{
|
||||||
|
// keep only one single '/' at the beginning - needed for cleanHomeDirPath()
|
||||||
|
while (path[0] == '/' && path[1] == '/')
|
||||||
|
path.remove(0,1);
|
||||||
|
|
||||||
|
// we probably should escape any $ ` and \ characters that may occur in the path, but the Qt code that reads back
|
||||||
|
// the file doesn't unescape them so not much point in doing so
|
||||||
|
|
||||||
|
// All of the 3 following functions to return the user's home directory
|
||||||
|
// can return different paths. We have to test all them.
|
||||||
|
const QString homeDir0 = QFile::decodeName(qgetenv("HOME"));
|
||||||
|
const QString homeDir1 = QDir::homePath();
|
||||||
|
const QString homeDir2 = QDir(homeDir1).canonicalPath();
|
||||||
|
if (cleanHomeDirPath(path, homeDir0) ||
|
||||||
|
cleanHomeDirPath(path, homeDir1) ||
|
||||||
|
cleanHomeDirPath(path, homeDir2) ) {
|
||||||
|
// kDebug() << "Path was replaced\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPathConfig::save()
|
||||||
|
{
|
||||||
|
KSharedConfig::Ptr config = KGlobal::config();
|
||||||
|
KConfigGroup configGroup( config, "Paths" );
|
||||||
|
|
||||||
|
bool pathChanged = false;
|
||||||
|
|
||||||
|
KUrl desktopURL( KGlobalSettings::desktopPath() );
|
||||||
|
|
||||||
|
if ( !urDesktop->url().equals( desktopURL, KUrl::RemoveTrailingSlash ) )
|
||||||
{
|
{
|
||||||
// We can't use KGlobalSettings::desktopPath() here, since it returns the home dir
|
// Test which other paths were inside this one (as it is by default)
|
||||||
// if the desktop folder doesn't exist.
|
// and for each, test where it should go.
|
||||||
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
// * Inside destination -> let them be moved with the desktop (but adjust name if necessary)
|
||||||
if (desktopPath.isEmpty()) {
|
// * Not inside destination -> move first
|
||||||
desktopPath = QDir::homePath() + "/Desktop";
|
// !!!
|
||||||
}
|
kDebug() << "desktopURL=" << desktopURL;
|
||||||
|
QString urlDesktop = urDesktop->url().toLocalFile();
|
||||||
|
if ( !urlDesktop.endsWith('/'))
|
||||||
|
urlDesktop+='/';
|
||||||
|
|
||||||
// Create the desktop folder if it doesn't exist
|
if ( moveDir( KUrl( KGlobalSettings::desktopPath() ), KUrl( urlDesktop ), i18n("Desktop") ) )
|
||||||
bool desktopIsEmpty = false;
|
{
|
||||||
const QDir desktopDir(desktopPath);
|
//save in XDG path
|
||||||
if (!desktopDir.exists()) {
|
const QString userDirsFile(KGlobal::dirs()->localxdgconfdir() + QLatin1String("user-dirs.dirs"));
|
||||||
::mkdir(QFile::encodeName(desktopPath), S_IRWXU);
|
KConfig xdgUserConf( userDirsFile, KConfig::SimpleConfig );
|
||||||
desktopIsEmpty = true;
|
KConfigGroup g( &xdgUserConf, "" );
|
||||||
} else {
|
g.writeEntry( "XDG_DESKTOP_DIR", QString("\"" + translatePath( urlDesktop ) + "\"") );
|
||||||
desktopIsEmpty = desktopDir.entryList(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot).isEmpty();
|
pathChanged = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (desktopIsEmpty) {
|
|
||||||
// Copy the desktop links and .directory file
|
|
||||||
const QStringList links = KGlobal::dirs()->findAllResources("data", "kcm_desktoppaths/*", KStandardDirs::NoDuplicates);
|
|
||||||
foreach (const QString &link, links) {
|
|
||||||
QString linkname = link.mid(link.lastIndexOf('/'));
|
|
||||||
// NOTE: special case for the .directory file, it is .desktop file but hidden one
|
|
||||||
if (linkname.startsWith(QLatin1String("/directory."))) {
|
|
||||||
linkname = QString::fromLatin1("/.directory");
|
|
||||||
// NOTE: .desktop file but extension does not matter and is better chopped
|
|
||||||
} else if (linkname.endsWith(QLatin1String(".desktop"))) {
|
|
||||||
linkname.chop(8);
|
|
||||||
}
|
|
||||||
QFile::copy(link, desktopPath + linkname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config->sync();
|
||||||
|
|
||||||
|
if (xdgSavePath(urDocument, KGlobalSettings::documentPath(), "XDG_DOCUMENTS_DIR", i18n("Documents")))
|
||||||
|
pathChanged = true;
|
||||||
|
|
||||||
|
if (xdgSavePath(urDownload, KGlobalSettings::downloadPath(), "XDG_DOWNLOAD_DIR", i18n("Downloads")))
|
||||||
|
pathChanged = true;
|
||||||
|
|
||||||
|
if (xdgSavePath(urMovie, KGlobalSettings::videosPath(), "XDG_VIDEOS_DIR", i18n("Movies")))
|
||||||
|
pathChanged = true;
|
||||||
|
|
||||||
|
if (xdgSavePath(urPicture, KGlobalSettings::picturesPath(), "XDG_PICTURES_DIR", i18n("Pictures")))
|
||||||
|
pathChanged = true;
|
||||||
|
|
||||||
|
if (xdgSavePath(urMusic, KGlobalSettings::musicPath(), "XDG_MUSIC_DIR", i18n("Music")))
|
||||||
|
pathChanged = true;
|
||||||
|
|
||||||
|
if (pathChanged) {
|
||||||
|
kDebug() << "sending message SettingsChanged";
|
||||||
|
KGlobalSettings::self()->emitChange(KGlobalSettings::PathsChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DesktopPathConfig::xdgSavePath(KUrlRequester* ur, const KUrl& currentUrl, const char* xdgKey, const QString& type)
|
||||||
|
{
|
||||||
|
KUrl newUrl = ur->url();
|
||||||
|
//url might be empty, use QDir::homePath (the default for xdg) then
|
||||||
|
if (!newUrl.isValid()) {
|
||||||
|
newUrl = KUrl(QDir::homePath());
|
||||||
|
}
|
||||||
|
if (!newUrl.equals(currentUrl, KUrl::RemoveTrailingSlash)) {
|
||||||
|
const QString path = newUrl.toLocalFile();
|
||||||
|
if (!QDir(path).exists()) {
|
||||||
|
// Check permissions
|
||||||
|
if (KStandardDirs::makeDir(path)) {
|
||||||
|
QDir().rmdir(path); // rmdir again, so that we get a fast rename
|
||||||
|
} else {
|
||||||
|
KMessageBox::sorry(this, KIO::buildErrorString(KIO::ERR_COULD_NOT_MKDIR, path));
|
||||||
|
ur->setUrl(currentUrl); // revert
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (moveDir(currentUrl, newUrl, type)) {
|
||||||
|
//save in XDG user-dirs.dirs config file, this is where KGlobalSettings/QStandardPaths reads from.
|
||||||
|
const QString userDirsFile(KGlobal::dirs()->localxdgconfdir() + QLatin1String("user-dirs.dirs"));
|
||||||
|
KConfig xdgUserConf(userDirsFile, KConfig::SimpleConfig);
|
||||||
|
KConfigGroup g(&xdgUserConf, "");
|
||||||
|
g.writeEntry(xdgKey, QString("\"" + translatePath(path) + "\""));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopPathConfig::moveDir( const KUrl & src, const KUrl & dest, const QString & type )
|
||||||
|
{
|
||||||
|
if (!src.isLocalFile() || !dest.isLocalFile())
|
||||||
|
return true;
|
||||||
|
if (!QDir(src.toLocalFile()).exists())
|
||||||
|
return true;
|
||||||
|
// Do not move $HOME! #193057
|
||||||
|
const QString translatedPath = translatePath(src.toLocalFile());
|
||||||
|
if (translatedPath == "$HOME" || translatedPath == "$HOME/") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ok = true;
|
||||||
|
|
||||||
|
QString question;
|
||||||
|
KGuiItem yesItem;
|
||||||
|
KGuiItem noItem;
|
||||||
|
const bool destExists = QDir(dest.toLocalFile()).exists();
|
||||||
|
if (destExists) {
|
||||||
|
// TODO: check if the src dir is empty? Nothing to move, then...
|
||||||
|
question = i18n("The path for '%1' has been changed.\nDo you want the files to be moved from '%2' to '%3'?",
|
||||||
|
type, src.toLocalFile(),
|
||||||
|
dest.toLocalFile());
|
||||||
|
yesItem = KGuiItem(i18nc("Move files from old to new place", "Move"));
|
||||||
|
noItem = KGuiItem(i18nc("Use the new directory but do not move files", "Do not Move"));
|
||||||
|
} else {
|
||||||
|
question = i18n("The path for '%1' has been changed.\nDo you want to move the directory '%2' to '%3'?",
|
||||||
|
type, src.toLocalFile(),
|
||||||
|
dest.toLocalFile());
|
||||||
|
yesItem = KGuiItem(i18nc("Move the directory", "Move"));
|
||||||
|
noItem = KGuiItem(i18nc("Use the new directory but do not move anything", "Do not Move"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask for confirmation before moving the files
|
||||||
|
if (KMessageBox::questionYesNo(this, question, i18n("Confirmation Required"),
|
||||||
|
yesItem, noItem)
|
||||||
|
== KMessageBox::Yes )
|
||||||
|
{
|
||||||
|
if (destExists) {
|
||||||
|
// Destination already exists -- should always be the case, for most types,
|
||||||
|
// but maybe not for the complex autostart case (to be checked...)
|
||||||
|
m_copyToDest = dest;
|
||||||
|
m_copyFromSrc = src;
|
||||||
|
KIO::ListJob* job = KIO::listDir( src );
|
||||||
|
job->setAutoDelete(false); // see <noautodelete> below
|
||||||
|
job->ui()->setWindow(this);
|
||||||
|
job->ui()->setAutoErrorHandlingEnabled(true);
|
||||||
|
connect(job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
|
||||||
|
this, SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList)));
|
||||||
|
// slotEntries will move every file/subdir individually into the dest
|
||||||
|
job->exec();
|
||||||
|
if (m_ok) {
|
||||||
|
QDir().rmdir(src.toLocalFile()); // hopefully it's empty by now
|
||||||
|
}
|
||||||
|
delete job;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kDebug() << "Direct move from" << src << "to" << dest;
|
||||||
|
KIO::Job * job = KIO::move( src, dest );
|
||||||
|
job->ui()->setWindow(this);
|
||||||
|
connect(job, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
|
||||||
|
job->exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kDebug() << "DesktopPathConfig::slotResult returning " << m_ok;
|
||||||
|
return m_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPathConfig::slotEntries(KIO::Job*, const KIO::UDSEntryList& list)
|
||||||
|
{
|
||||||
|
QListIterator<KIO::UDSEntry> it(list);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
KFileItem file(it.next(), m_copyFromSrc, true, true);
|
||||||
|
kDebug() << file.url();
|
||||||
|
if (file.url() == m_copyFromSrc || file.url().fileName() == "..") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
KIO::Job * moveJob = KIO::move(file.url(), m_copyToDest);
|
||||||
|
moveJob->ui()->setWindow(this);
|
||||||
|
connect(moveJob, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
|
||||||
|
moveJob->exec(); // sub-event loop here. <noautodelete>: the main job is not autodeleted because it would be deleted here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesktopPathConfig::slotResult( KJob * job )
|
||||||
|
{
|
||||||
|
if (job->error()) {
|
||||||
|
if ( job->error() != KIO::ERR_DOES_NOT_EXIST )
|
||||||
|
m_ok = false;
|
||||||
|
|
||||||
|
// If the source doesn't exist, no wonder we couldn't move the dir.
|
||||||
|
// In that case, trust the user and set the new setting in any case.
|
||||||
|
|
||||||
|
static_cast<KIO::Job*>(job)->ui()->showErrorMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_kcmdesktoppaths.cpp"
|
||||||
|
|
|
@ -1,27 +1,83 @@
|
||||||
/* This file is part of the KDE project
|
/**
|
||||||
Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>
|
* Copyright (c) Martin R. Jones 1996
|
||||||
|
* Copyright 1998-2007 David Faure <faure@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
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
// Summarized history:
|
||||||
modify it under the terms of the GNU Library General Public
|
//
|
||||||
License version 2 as published by the Free Software Foundation.
|
// "Desktop Icons Options" Tab for KDesktop configuration
|
||||||
|
// Martin Jones
|
||||||
This library is distributed in the hope that it will be useful,
|
//
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// Port to KControl, split from "Misc" Tab, Port to KControl2
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
// (c) David Faure 1998
|
||||||
Library General Public License for more details.
|
// Desktop menus, paths
|
||||||
|
// (c) David Faure 2000
|
||||||
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 KCMDESKTOPPATHS_H
|
#ifndef KCMDESKTOPPATHS_H
|
||||||
#define KCMDESKTOPPATHS_H
|
#define KCMDESKTOPPATHS_H
|
||||||
|
|
||||||
#include <KPluginFactory>
|
#include <kcmodule.h>
|
||||||
|
#include <kio/global.h>
|
||||||
|
#include <kio/udsentry.h>
|
||||||
|
#include <kurl.h>
|
||||||
|
|
||||||
K_PLUGIN_FACTORY_DECLARATION(KcmDesktopPaths)
|
#include <QFormLayout>
|
||||||
|
class KJob;
|
||||||
|
class KUrlRequester;
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace KIO { class Job; }
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// The "Path" Tab contains :
|
||||||
|
// The paths for Desktop, Autostart and Documents
|
||||||
|
|
||||||
|
class DesktopPathConfig : public KCModule
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
DesktopPathConfig( QWidget *parent, const QVariantList &args );
|
||||||
|
virtual void load();
|
||||||
|
virtual void save();
|
||||||
|
virtual void defaults();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void slotEntries( KIO::Job * job, const KIO::UDSEntryList& list);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KUrlRequester* addRow(QFormLayout *lay, const QString& label, const QString& whatsThis);
|
||||||
|
bool xdgSavePath(KUrlRequester* ur, const KUrl& currentUrl, const char* xdgKey, const QString& type);
|
||||||
|
|
||||||
|
// Desktop Paths
|
||||||
|
KUrlRequester *urDesktop;
|
||||||
|
KUrlRequester *urDocument;
|
||||||
|
KUrlRequester *urDownload;
|
||||||
|
KUrlRequester *urMovie;
|
||||||
|
KUrlRequester *urPicture;
|
||||||
|
KUrlRequester *urMusic;
|
||||||
|
|
||||||
|
bool moveDir( const KUrl & src, const KUrl & dest, const QString & type );
|
||||||
|
bool m_ok;
|
||||||
|
KUrl m_copyToDest; // used when the destination directory already exists
|
||||||
|
KUrl m_copyFromSrc;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void slotResult( KJob * job );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // KCMDESKTOPPATHS_H
|
|
||||||
|
|
65
kcontrol/desktoppaths/kdesktoppaths.cpp
Normal file
65
kcontrol/desktoppaths/kdesktoppaths.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/* This file is part of the KDE project
|
||||||
|
Copyright (C) 2006-2007 Matthias Kretz <kretz@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.
|
||||||
|
|
||||||
|
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 <QStandardPaths>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <KStandardDirs>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// application instance for events processing
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
// can't use KGlobalSettings::desktopPath() here, since it returns the home dir
|
||||||
|
// if the desktop folder doesn't exist.
|
||||||
|
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||||
|
if (desktopPath.isEmpty()) {
|
||||||
|
desktopPath = QDir::homePath() + "/Desktop";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the desktop folder if it doesn't exist
|
||||||
|
bool desktopIsEmpty = false;
|
||||||
|
const QDir desktopDir(desktopPath);
|
||||||
|
if (!desktopDir.exists()) {
|
||||||
|
::mkdir(QFile::encodeName(desktopPath), S_IRWXU);
|
||||||
|
desktopIsEmpty = true;
|
||||||
|
} else {
|
||||||
|
desktopIsEmpty = desktopDir.entryList(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desktopIsEmpty) {
|
||||||
|
// Copy the desktop links and .directory file
|
||||||
|
const QStringList links = KGlobal::dirs()->findAllResources("data", "kcm_desktoppaths/*", KStandardDirs::NoDuplicates);
|
||||||
|
foreach (const QString &link, links) {
|
||||||
|
QString linkname = link.mid(link.lastIndexOf('/'));
|
||||||
|
// NOTE: special case for the .directory file, it is .desktop file but hidden one
|
||||||
|
if (linkname.startsWith(QLatin1String("/directory."))) {
|
||||||
|
linkname = QString::fromLatin1("/.directory");
|
||||||
|
// NOTE: .desktop file but extension does not matter and is better chopped
|
||||||
|
} else if (linkname.endsWith(QLatin1String(".desktop"))) {
|
||||||
|
linkname.chop(8);
|
||||||
|
}
|
||||||
|
QFile::copy(link, desktopPath + linkname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
9
kcontrol/desktoppaths/kdesktoppaths.desktop
Normal file
9
kcontrol/desktoppaths/kdesktoppaths.desktop
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Service
|
||||||
|
Name=KDE Desktop Paths
|
||||||
|
Exec=kdesktoppaths
|
||||||
|
Icon=system-file-manager
|
||||||
|
StartupNotify=false
|
||||||
|
OnlyShowIn=KDE;
|
||||||
|
X-KDE-autostart-phase=1
|
||||||
|
X-DocPath=kcontrol/paths/index.html
|
|
@ -57,7 +57,13 @@ install(
|
||||||
|
|
||||||
########### next target ###############
|
########### next target ###############
|
||||||
|
|
||||||
set(kcm_input_PART_SRCS mouse.cpp main.cpp logitechmouse.cpp kmousedlg.ui logitechmouse_base.ui )
|
set(kcm_input_PART_SRCS
|
||||||
|
mouse.cpp
|
||||||
|
mousesettings.cpp
|
||||||
|
logitechmouse.cpp
|
||||||
|
kmousedlg.ui
|
||||||
|
logitechmouse_base.ui
|
||||||
|
)
|
||||||
|
|
||||||
kde4_add_plugin(kcm_input ${kcm_input_PART_SRCS})
|
kde4_add_plugin(kcm_input ${kcm_input_PART_SRCS})
|
||||||
|
|
||||||
|
@ -101,6 +107,27 @@ install(
|
||||||
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
|
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
########### next target ###############
|
||||||
|
|
||||||
|
add_executable(kmouse
|
||||||
|
kmouse.cpp
|
||||||
|
logitechmouse.cpp
|
||||||
|
mousesettings.cpp
|
||||||
|
logitechmouse_base.ui
|
||||||
|
)
|
||||||
|
target_link_libraries(kmouse
|
||||||
|
KDE4::kdeui
|
||||||
|
${X11_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (LIBUSB_FOUND)
|
||||||
|
target_link_libraries(kmouse ${LIBUSB_LIBRARIES})
|
||||||
|
endif (LIBUSB_FOUND)
|
||||||
|
if (X11_Xcursor_FOUND)
|
||||||
|
target_link_libraries(kmouse ${X11_Xcursor_LIB})
|
||||||
|
endif (X11_Xcursor_FOUND)
|
||||||
|
|
||||||
########### install files ###############
|
########### install files ###############
|
||||||
|
|
||||||
install(
|
install(
|
||||||
|
@ -117,3 +144,13 @@ install(
|
||||||
FILES mouse_new.desktop
|
FILES mouse_new.desktop
|
||||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/solid/actions
|
DESTINATION ${KDE4_DATA_INSTALL_DIR}/solid/actions
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS kmouse
|
||||||
|
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES kmouse.desktop
|
||||||
|
DESTINATION ${KDE4_AUTOSTART_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
77
kcontrol/input/kmouse.cpp
Normal file
77
kcontrol/input/kmouse.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* kmouse.cpp
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@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
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config-X11.h>
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QX11Info>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <KConfig>
|
||||||
|
#include <KConfigGroup>
|
||||||
|
#include <KGlobalSettings>
|
||||||
|
#include <KToolInvocation>
|
||||||
|
#include <KDebug>
|
||||||
|
|
||||||
|
#include "mousesettings.h"
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#ifdef HAVE_XCURSOR
|
||||||
|
# include <X11/Xcursor/Xcursor.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// application instance for QX11Info::display()
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
KConfig *config = new KConfig("kcminputrc", KConfig::NoGlobals);
|
||||||
|
MouseSettings settings;
|
||||||
|
settings.load(config);
|
||||||
|
settings.apply(true); // force
|
||||||
|
|
||||||
|
// NOTE: keep in sync with:
|
||||||
|
// kcontrol/input/kapplymousetheme.cpp
|
||||||
|
#ifdef HAVE_XCURSOR
|
||||||
|
KConfigGroup group = config->group("Mouse");
|
||||||
|
const QByteArray theme = group.readEntry("cursorTheme", QByteArray(KDE_DEFAULT_CURSOR_THEME));
|
||||||
|
const QByteArray size = group.readEntry("cursorSize", QByteArray());
|
||||||
|
|
||||||
|
// Apply the KDE cursor theme to ourselves
|
||||||
|
XcursorSetTheme(QX11Info::display(), theme.constData());
|
||||||
|
|
||||||
|
if (!size.isEmpty()) {
|
||||||
|
XcursorSetDefaultSize(QX11Info::display(), size.toUInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the default cursor from the theme and apply it to the root window.
|
||||||
|
Cursor handle = XcursorLibraryLoadCursor(QX11Info::display(), "left_ptr");
|
||||||
|
XDefineCursor(QX11Info::display(), QX11Info::appRootWindow(), handle);
|
||||||
|
XFreeCursor(QX11Info::display(), handle); // Don't leak the cursor
|
||||||
|
|
||||||
|
// Tell klauncher to set the XCURSOR_THEME and XCURSOR_SIZE environment
|
||||||
|
// variables when launching applications.
|
||||||
|
KToolInvocation::self()->setLaunchEnv("XCURSOR_THEME", theme);
|
||||||
|
if (!size.isEmpty()) {
|
||||||
|
KToolInvocation::self()->setLaunchEnv("XCURSOR_SIZE", size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
delete config;
|
||||||
|
return 0;
|
||||||
|
}
|
9
kcontrol/input/kmouse.desktop
Normal file
9
kcontrol/input/kmouse.desktop
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Service
|
||||||
|
Name=KDE Mouse
|
||||||
|
Exec=kmouse
|
||||||
|
Icon=preferences-desktop-mouse
|
||||||
|
StartupNotify=false
|
||||||
|
OnlyShowIn=KDE;
|
||||||
|
X-KDE-autostart-phase=0
|
||||||
|
X-DocPath=kcontrol/mouse/index.html
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* main.cpp
|
|
||||||
*
|
|
||||||
* Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
|
|
||||||
*
|
|
||||||
* Requires the Qt widget libraries, available at no cost at
|
|
||||||
* http://www.troll.no/
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config-X11.h>
|
|
||||||
|
|
||||||
#include <klocale.h>
|
|
||||||
#include <kglobal.h>
|
|
||||||
#include <kconfig.h>
|
|
||||||
#include <QFile>
|
|
||||||
|
|
||||||
#include "mouse.h"
|
|
||||||
#include <QtGui/qx11info_x11.h>
|
|
||||||
|
|
||||||
#include <ktoolinvocation.h>
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#ifdef HAVE_XCURSOR
|
|
||||||
# include <X11/Xcursor/Xcursor.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
Q_DECL_EXPORT void kcminit_mouse()
|
|
||||||
{
|
|
||||||
KConfig *config = new KConfig("kcminputrc", KConfig::NoGlobals );
|
|
||||||
MouseSettings settings;
|
|
||||||
settings.load(config);
|
|
||||||
settings.apply(true); // force
|
|
||||||
|
|
||||||
// NOTE: keep in sync with:
|
|
||||||
// kcontrol/input/kapplymousetheme.cpp
|
|
||||||
#ifdef HAVE_XCURSOR
|
|
||||||
KConfigGroup group = config->group("Mouse");
|
|
||||||
const QByteArray theme = group.readEntry("cursorTheme", QByteArray(KDE_DEFAULT_CURSOR_THEME));
|
|
||||||
const QByteArray size = group.readEntry("cursorSize", QByteArray());
|
|
||||||
|
|
||||||
// Apply the KDE cursor theme to ourselves
|
|
||||||
XcursorSetTheme(QX11Info::display(), theme.constData());
|
|
||||||
|
|
||||||
if (!size.isEmpty()) {
|
|
||||||
XcursorSetDefaultSize(QX11Info::display(), size.toUInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the default cursor from the theme and apply it to the root window.
|
|
||||||
Cursor handle = XcursorLibraryLoadCursor(QX11Info::display(), "left_ptr");
|
|
||||||
XDefineCursor(QX11Info::display(), QX11Info::appRootWindow(), handle);
|
|
||||||
XFreeCursor(QX11Info::display(), handle); // Don't leak the cursor
|
|
||||||
|
|
||||||
// Tell klauncher to set the XCURSOR_THEME and XCURSOR_SIZE environment
|
|
||||||
// variables when launching applications.
|
|
||||||
KToolInvocation::self()->setLaunchEnv("XCURSOR_THEME", theme);
|
|
||||||
if (!size.isEmpty()) {
|
|
||||||
KToolInvocation::self()->setLaunchEnv("XCURSOR_SIZE", size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
delete config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,10 @@
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#undef Below
|
|
||||||
#undef Above
|
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QWhatsThis>
|
#include <QWhatsThis>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
#include <QX11Info>
|
||||||
|
|
||||||
#include <ktoolinvocation.h>
|
#include <ktoolinvocation.h>
|
||||||
#include <klocale.h>
|
#include <klocale.h>
|
||||||
|
@ -72,11 +71,6 @@
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <kglobalsettings.h>
|
|
||||||
#include <QtGui/qx11info_x11.h>
|
|
||||||
|
|
||||||
#undef Below
|
|
||||||
|
|
||||||
|
|
||||||
K_PLUGIN_FACTORY(MouseConfigFactory,
|
K_PLUGIN_FACTORY(MouseConfigFactory,
|
||||||
registerPlugin<MouseConfig>(); // mouse
|
registerPlugin<MouseConfig>(); // mouse
|
||||||
|
@ -609,87 +603,6 @@ void MouseConfig::slotHandedChanged(int val){
|
||||||
settings->m_handedNeedsApply = true;
|
settings->m_handedNeedsApply = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseSettings::load(KConfig *config)
|
|
||||||
{
|
|
||||||
int accel_num, accel_den, threshold;
|
|
||||||
double accel;
|
|
||||||
XGetPointerControl( QX11Info::display(),
|
|
||||||
&accel_num, &accel_den, &threshold );
|
|
||||||
accel = float(accel_num) / float(accel_den);
|
|
||||||
|
|
||||||
// get settings from X server
|
|
||||||
int h = RIGHT_HANDED;
|
|
||||||
unsigned char map[20];
|
|
||||||
num_buttons = XGetPointerMapping(QX11Info::display(), map, 20);
|
|
||||||
|
|
||||||
handedEnabled = true;
|
|
||||||
|
|
||||||
// ## keep this in sync with KGlobalSettings::mouseSettings
|
|
||||||
if( num_buttons == 1 )
|
|
||||||
{
|
|
||||||
/* disable button remapping */
|
|
||||||
handedEnabled = false;
|
|
||||||
}
|
|
||||||
else if( num_buttons == 2 )
|
|
||||||
{
|
|
||||||
if ( (int)map[0] == 1 && (int)map[1] == 2 )
|
|
||||||
h = RIGHT_HANDED;
|
|
||||||
else if ( (int)map[0] == 2 && (int)map[1] == 1 )
|
|
||||||
h = LEFT_HANDED;
|
|
||||||
else
|
|
||||||
/* custom button setup: disable button remapping */
|
|
||||||
handedEnabled = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
middle_button = (int)map[1];
|
|
||||||
if ( (int)map[0] == 1 && (int)map[2] == 3 )
|
|
||||||
h = RIGHT_HANDED;
|
|
||||||
else if ( (int)map[0] == 3 && (int)map[2] == 1 )
|
|
||||||
h = LEFT_HANDED;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* custom button setup: disable button remapping */
|
|
||||||
handedEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KConfigGroup group = config->group("Mouse");
|
|
||||||
double a = group.readEntry("Acceleration",-1.0);
|
|
||||||
if (a == -1)
|
|
||||||
accelRate = accel;
|
|
||||||
else
|
|
||||||
accelRate = a;
|
|
||||||
|
|
||||||
int t = group.readEntry("Threshold",-1);
|
|
||||||
if (t == -1)
|
|
||||||
thresholdMove = threshold;
|
|
||||||
else
|
|
||||||
thresholdMove = t;
|
|
||||||
|
|
||||||
QString key = group.readEntry("MouseButtonMapping");
|
|
||||||
if (key == "RightHanded")
|
|
||||||
handed = RIGHT_HANDED;
|
|
||||||
else if (key == "LeftHanded")
|
|
||||||
handed = LEFT_HANDED;
|
|
||||||
#warning was key == NULL how was this working? is key.isNull() what the coder meant?
|
|
||||||
else if (key.isNull())
|
|
||||||
handed = h;
|
|
||||||
reverseScrollPolarity = group.readEntry( "ReverseScrollPolarity", false);
|
|
||||||
m_handedNeedsApply = false;
|
|
||||||
|
|
||||||
// SC/DC/AutoSelect/ChangeCursor
|
|
||||||
group = config->group("KDE");
|
|
||||||
doubleClickInterval = group.readEntry("DoubleClickInterval", 400);
|
|
||||||
dragStartTime = group.readEntry("StartDragTime", 500);
|
|
||||||
dragStartDist = group.readEntry("StartDragDist", 4);
|
|
||||||
wheelScrollLines = group.readEntry("WheelScrollLines", 3);
|
|
||||||
|
|
||||||
singleClick = group.readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK);
|
|
||||||
autoSelectDelay = group.readEntry("AutoSelectDelay", KDE_DEFAULT_AUTOSELECTDELAY);
|
|
||||||
changeCursor = group.readEntry("ChangeCursor", KDE_DEFAULT_CHANGECURSOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseConfig::slotThreshChanged(int value)
|
void MouseConfig::slotThreshChanged(int value)
|
||||||
{
|
{
|
||||||
thresh->setSuffix(i18np(" pixel", " pixels", value));
|
thresh->setSuffix(i18np(" pixel", " pixels", value));
|
||||||
|
@ -705,113 +618,6 @@ void MouseConfig::slotWheelScrollLinesChanged(int value)
|
||||||
wheelScrollLines->setSuffix(i18np(" line", " lines", value));
|
wheelScrollLines->setSuffix(i18np(" line", " lines", value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseSettings::apply(bool force)
|
|
||||||
{
|
|
||||||
XChangePointerControl( QX11Info::display(),
|
|
||||||
true, true, int(qRound(accelRate*10)), 10, thresholdMove);
|
|
||||||
|
|
||||||
// 256 might seems extreme, but X has already been known to return 32,
|
|
||||||
// and we don't want to truncate things. Xlib limits the table to 256 bytes,
|
|
||||||
// so it's a good uper bound..
|
|
||||||
unsigned char map[256];
|
|
||||||
num_buttons = XGetPointerMapping(QX11Info::display(), map, 256);
|
|
||||||
|
|
||||||
int remap=(num_buttons>=1);
|
|
||||||
if (handedEnabled && (m_handedNeedsApply || force)) {
|
|
||||||
if( num_buttons == 1 )
|
|
||||||
{
|
|
||||||
map[0] = (unsigned char) 1;
|
|
||||||
}
|
|
||||||
else if( num_buttons == 2 )
|
|
||||||
{
|
|
||||||
if (handed == RIGHT_HANDED)
|
|
||||||
{
|
|
||||||
map[0] = (unsigned char) 1;
|
|
||||||
map[1] = (unsigned char) 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map[0] = (unsigned char) 3;
|
|
||||||
map[1] = (unsigned char) 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // 3 buttons and more
|
|
||||||
{
|
|
||||||
if (handed == RIGHT_HANDED)
|
|
||||||
{
|
|
||||||
map[0] = (unsigned char) 1;
|
|
||||||
map[1] = (unsigned char) middle_button;
|
|
||||||
map[2] = (unsigned char) 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
map[0] = (unsigned char) 3;
|
|
||||||
map[1] = (unsigned char) middle_button;
|
|
||||||
map[2] = (unsigned char) 1;
|
|
||||||
}
|
|
||||||
if( num_buttons >= 5 )
|
|
||||||
{
|
|
||||||
// Apps seem to expect logical buttons 4,5 are the vertical wheel.
|
|
||||||
// With mice with more than 3 buttons (not including wheel) the physical
|
|
||||||
// buttons mapped to logical 4,5 may not be physical 4,5 , so keep
|
|
||||||
// this mapping, only possibly reversing them.
|
|
||||||
int pos;
|
|
||||||
for( pos = 0; pos < num_buttons; ++pos )
|
|
||||||
if( map[pos] == 4 || map[pos] == 5 )
|
|
||||||
break;
|
|
||||||
if( pos < num_buttons - 1 )
|
|
||||||
{
|
|
||||||
map[pos] = reverseScrollPolarity ? (unsigned char) 5 : (unsigned char) 4;
|
|
||||||
map[pos+1] = reverseScrollPolarity ? (unsigned char) 4 : (unsigned char) 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int retval;
|
|
||||||
if (remap)
|
|
||||||
while ((retval=XSetPointerMapping(QX11Info::display(), map,
|
|
||||||
num_buttons)) == MappingBusy)
|
|
||||||
/* keep trying until the pointer is free */
|
|
||||||
{ };
|
|
||||||
m_handedNeedsApply = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This iterates through the various Logitech mice, if we have support.
|
|
||||||
#ifdef HAVE_LIBUSB
|
|
||||||
Q_FOREACH( LogitechMouse *logitechMouse, logitechMouseList ) {
|
|
||||||
logitechMouse->applyChanges();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseSettings::save(KConfig *config)
|
|
||||||
{
|
|
||||||
KConfigGroup group = config->group("Mouse");
|
|
||||||
group.writeEntry("Acceleration",accelRate);
|
|
||||||
group.writeEntry("Threshold",thresholdMove);
|
|
||||||
if (handed == RIGHT_HANDED)
|
|
||||||
group.writeEntry("MouseButtonMapping",QString("RightHanded"));
|
|
||||||
else
|
|
||||||
group.writeEntry("MouseButtonMapping",QString("LeftHanded"));
|
|
||||||
group.writeEntry( "ReverseScrollPolarity", reverseScrollPolarity );
|
|
||||||
|
|
||||||
group = config->group("KDE");
|
|
||||||
group.writeEntry("DoubleClickInterval", doubleClickInterval, KConfig::Persistent|KConfig::Global);
|
|
||||||
group.writeEntry("StartDragTime", dragStartTime, KConfig::Persistent|KConfig::Global);
|
|
||||||
group.writeEntry("StartDragDist", dragStartDist, KConfig::Persistent|KConfig::Global);
|
|
||||||
group.writeEntry("WheelScrollLines", wheelScrollLines, KConfig::Persistent|KConfig::Global);
|
|
||||||
group.writeEntry("SingleClick", singleClick, KConfig::Persistent|KConfig::Global);
|
|
||||||
group.writeEntry("AutoSelectDelay", autoSelectDelay, KConfig::Persistent|KConfig::Global);
|
|
||||||
group.writeEntry("ChangeCursor", changeCursor,KConfig::Persistent|KConfig::Global);
|
|
||||||
// This iterates through the various Logitech mice, if we have support.
|
|
||||||
#ifdef HAVE_LIBUSB
|
|
||||||
Q_FOREACH( LogitechMouse *logitechMouse, logitechMouseList ) {
|
|
||||||
logitechMouse->save(config);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
config->sync();
|
|
||||||
KGlobalSettings::self()->emitChange(KGlobalSettings::MouseChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseConfig::slotScrollPolarityChanged()
|
void MouseConfig::slotScrollPolarityChanged()
|
||||||
{
|
{
|
||||||
settings->m_handedNeedsApply = true;
|
settings->m_handedNeedsApply = true;
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
Exec=kcmshell4 mouse
|
Exec=kcmshell4 mouse
|
||||||
Icon=preferences-desktop-mouse
|
Icon=preferences-desktop-mouse
|
||||||
Type=Service
|
Type=Service
|
||||||
X-KDE-ServiceTypes=KCModule,KCModuleInit
|
X-KDE-ServiceTypes=KCModule
|
||||||
X-DocPath=kcontrol/mouse/index.html
|
X-DocPath=kcontrol/mouse/index.html
|
||||||
|
|
||||||
X-KDE-Library=kcm_input
|
X-KDE-Library=kcm_input
|
||||||
X-KDE-Init-Symbol=kcminit_mouse
|
|
||||||
X-KDE-Init-Phase=0
|
|
||||||
X-KDE-ParentApp=kcontrol
|
X-KDE-ParentApp=kcontrol
|
||||||
|
|
||||||
X-KDE-System-Settings-Parent-Category=input-devices
|
X-KDE-System-Settings-Parent-Category=input-devices
|
||||||
|
@ -201,7 +199,7 @@ X-KDE-Keywords[ca]=Ratolí,Acceleració de ratolí,Llindar de ratolí,Botons de
|
||||||
X-KDE-Keywords[ca@valencia]=Ratolí,Acceleració de ratolí,Llindar de ratolí,Botons de ratolí,Selecció,Ombra de cursor,Dispositius d'entrada,Mapatge de boton,Clic,icones,reacció,Apuntadors,Arrossegar,Clic doble,Clic normal,mapatge,dretà,esquerrà,Dispositiu apuntador,Roda de ratolí,Emulació de ratolí,Navegació amb ratolí,Arrossegar i deixar anar de ratolí,Desplaçament amb ratolí,Sensitivitat de ratolí,Moure el ratolí amb teclat numèric,Emulació de ratolí amb teclat numèric
|
X-KDE-Keywords[ca@valencia]=Ratolí,Acceleració de ratolí,Llindar de ratolí,Botons de ratolí,Selecció,Ombra de cursor,Dispositius d'entrada,Mapatge de boton,Clic,icones,reacció,Apuntadors,Arrossegar,Clic doble,Clic normal,mapatge,dretà,esquerrà,Dispositiu apuntador,Roda de ratolí,Emulació de ratolí,Navegació amb ratolí,Arrossegar i deixar anar de ratolí,Desplaçament amb ratolí,Sensitivitat de ratolí,Moure el ratolí amb teclat numèric,Emulació de ratolí amb teclat numèric
|
||||||
X-KDE-Keywords[da]=Mus,Museacceleration,musetærskel,museknapper,markering,markørform,Input-enheder,knapkobling,klik,ikoner,feedback,Pointers,træk,dobbeltklik,enkeltklik,kobling,højrehåndet,venstrehåndet,pegeenhed,musehjul,museemulering,musenavigation,træk og slip,muserulning,scrolling,musefølsomhed,bevæg mus med numerisk tastatur,markører,cursor,rulning
|
X-KDE-Keywords[da]=Mus,Museacceleration,musetærskel,museknapper,markering,markørform,Input-enheder,knapkobling,klik,ikoner,feedback,Pointers,træk,dobbeltklik,enkeltklik,kobling,højrehåndet,venstrehåndet,pegeenhed,musehjul,museemulering,musenavigation,træk og slip,muserulning,scrolling,musefølsomhed,bevæg mus med numerisk tastatur,markører,cursor,rulning
|
||||||
X-KDE-Keywords[de]=Maus,Mausbeschleunigung,Mausschwellwert,Maustasten,Auswahl,Cursor,Cursor-Form,Eingabegeräte,Knöpfe,Buttons,Zuordnungen,Klicks,Zeigegeräte,Doppelklick,Rechtshänder,Linkshänder,Ziehen,Mausrad,Maus-Emulation,Maus-Navigation,Ziehen und Ablegen mit der Maus,Blättern mit der Maus,Maus-Empfindlichkeit,Mauszeiger mit der Zahlentastatur verschieben,Maus-Emulation mit der Zahlentastatur
|
X-KDE-Keywords[de]=Maus,Mausbeschleunigung,Mausschwellwert,Maustasten,Auswahl,Cursor,Cursor-Form,Eingabegeräte,Knöpfe,Buttons,Zuordnungen,Klicks,Zeigegeräte,Doppelklick,Rechtshänder,Linkshänder,Ziehen,Mausrad,Maus-Emulation,Maus-Navigation,Ziehen und Ablegen mit der Maus,Blättern mit der Maus,Maus-Empfindlichkeit,Mauszeiger mit der Zahlentastatur verschieben,Maus-Emulation mit der Zahlentastatur
|
||||||
X-KDE-Keywords[el]=ποντίκι,επιτάχυνση ποντικιού,κατώφλι ποντικιού,κουμπιά ποντικιού,επιλογή,σχήμα δρομέα,συσκευές εισόδου,χαρτογράφηση κουμπιών,κλικ,εικονίδια,ανάδραση,δείκτες,έλξη,διπλό κλικ,μονό κλικ,χαρτογράφηση,δεξιόχειρας,αριστερόχειρας,συσκευή δείκτη,τροχός ποντικιού,εξομοίωση ποντικιού,πλοήγηση ποντικιού,έλξη και απόθεση ποντικιού,κύλιση ποντικιού,ευαισθησία ποντικιού,κίνηση ποντικιού με το αριθμητικό πληκτρολόγιο,εξομοίωση ποντικιού αριθμητικού πληκτρολογίου
|
X-KDE-Keywords[el]=πο<EFBFBD><EFBFBD>τίκι,επιτάχυνση ποντικιού,κατώφλι ποντικιού,κουμπιά ποντικιού,επιλογή,σχήμα δρομέα,συσκευές εισόδου,χαρτογράφηση κουμπιών,κλικ,εικονίδια,ανάδραση,δείκτες,έλξη,διπλό κλικ,μονό κλικ,χαρτογράφηση,δεξιόχειρας,αριστερόχειρας,συσκευή δείκτη,τροχός ποντικιού,εξομοίωση ποντικιού,πλοήγηση ποντικιού,έλξη και απόθεση ποντικιού,κύλιση ποντικιού,ευαισθησία ποντικιού,κίνηση ποντικιού με το αριθμητικό πληκτρολόγιο,εξομοίωση ποντικιού αριθμητικού πληκτρολογίου
|
||||||
X-KDE-Keywords[en_GB]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation
|
X-KDE-Keywords[en_GB]=Mouse,Mouse acceleration,Mouse threshold,Mouse buttons,Selection,Cursor Shape,Input Devices,Button Mapping,Click,icons,feedback,Pointers,Drag,Double Click,Single Click,mapping,right handed,left handed,Pointer Device,Mouse Wheel,Mouse Emulation,Mouse Navigation,Mouse Drag and Drop,Mouse Scrolling,Mouse Sensitivity,Move Mouse with Num Pad,Mouse Num Pad Emulation
|
||||||
X-KDE-Keywords[es]=Ratón,Aceleración de ratón,Umbral del ratón,Botones del ratón,Selección,Forma del cursor,Dispositivos de entrada,Mapeo de botones,Clic,iconos,reacción,Punteros,Arrastrar,Doble clic,clic sencillo,mapeo,diestro,zurdo,Dispositivo apuntador,Rueda del ratón,Emulación del ratón,Navegación con el ratón,Arrastrar y soltar con el ratón,Desplazamiento con el ratón,Sensibilidad del ratón,Mover el ratón con el teclado numérico,Emulación del ratón con el teclado numérico
|
X-KDE-Keywords[es]=Ratón,Aceleración de ratón,Umbral del ratón,Botones del ratón,Selección,Forma del cursor,Dispositivos de entrada,Mapeo de botones,Clic,iconos,reacción,Punteros,Arrastrar,Doble clic,clic sencillo,mapeo,diestro,zurdo,Dispositivo apuntador,Rueda del ratón,Emulación del ratón,Navegación con el ratón,Arrastrar y soltar con el ratón,Desplazamiento con el ratón,Sensibilidad del ratón,Mover el ratón con el teclado numérico,Emulación del ratón con el teclado numérico
|
||||||
X-KDE-Keywords[et]=hiir,hiire kiirendamine,hiire lävi,hiirenupud,valik,kursori kuju,sisendseadmed,nuppude seostamine,klõps,klõpsamine,ikoonid,tagasiside,lohistamine,topeltklõps,ühekordne klõps,seostamine,paremakäelised,vasakukäelised,osutusseade,hiireratas,hiire emuleerimine,hiirega liikumine,hiirega lohistamine,hiirega kerimine,hiire tundlikkus,hiire liigutamine numbriklahvistikuga,hiire numbriklahvistiku emuleerimine
|
X-KDE-Keywords[et]=hiir,hiire kiirendamine,hiire lävi,hiirenupud,valik,kursori kuju,sisendseadmed,nuppude seostamine,klõps,klõpsamine,ikoonid,tagasiside,lohistamine,topeltklõps,ühekordne klõps,seostamine,paremakäelised,vasakukäelised,osutusseade,hiireratas,hiire emuleerimine,hiirega liikumine,hiirega lohistamine,hiirega kerimine,hiire tundlikkus,hiire liigutamine numbriklahvistikuga,hiire numbriklahvistiku emuleerimine
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#define __MOUSECONFIG_H__
|
#define __MOUSECONFIG_H__
|
||||||
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QtGui/QLCDNumber>
|
#include <QLCDNumber>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QRadioButton>
|
#include <QRadioButton>
|
||||||
|
|
||||||
|
@ -46,13 +46,11 @@
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
#include "logitechmouse.h"
|
#include "logitechmouse.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "mousesettings.h"
|
||||||
|
|
||||||
#include <kcmodule.h>
|
#include <kcmodule.h>
|
||||||
#include "ui_kmousedlg.h"
|
#include "ui_kmousedlg.h"
|
||||||
|
|
||||||
#define RIGHT_HANDED 0
|
|
||||||
#define LEFT_HANDED 1
|
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
@ -65,36 +63,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class MouseSettings
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void save(KConfig *);
|
|
||||||
void load(KConfig *);
|
|
||||||
void apply(bool force=false);
|
|
||||||
public:
|
|
||||||
int num_buttons;
|
|
||||||
int middle_button;
|
|
||||||
bool handedEnabled;
|
|
||||||
bool m_handedNeedsApply;
|
|
||||||
int handed;
|
|
||||||
double accelRate;
|
|
||||||
int thresholdMove;
|
|
||||||
int doubleClickInterval;
|
|
||||||
int dragStartTime;
|
|
||||||
int dragStartDist;
|
|
||||||
bool singleClick;
|
|
||||||
int autoSelectDelay;
|
|
||||||
bool changeCursor;
|
|
||||||
int wheelScrollLines;
|
|
||||||
bool reverseScrollPolarity;
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBUSB
|
|
||||||
// TODO: In Qt4, replace with a better container.
|
|
||||||
QList <LogitechMouse*> logitechMouseList;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class MouseConfig : public KCModule
|
class MouseConfig : public KCModule
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
244
kcontrol/input/mousesettings.cpp
Normal file
244
kcontrol/input/mousesettings.cpp
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
/*
|
||||||
|
* mousesettings.cpp
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca
|
||||||
|
*
|
||||||
|
* Layout management, enhancements:
|
||||||
|
* Copyright (c) 1999 Dirk A. Mueller <dmuell@gmx.net>
|
||||||
|
*
|
||||||
|
* SC/DC/AutoSelect/ChangeCursor:
|
||||||
|
* Copyright (c) 2000 David Faure <faure@kde.org>
|
||||||
|
*
|
||||||
|
* Double click interval, drag time & dist
|
||||||
|
* Copyright (c) 2000 Bernd Gehrmann
|
||||||
|
*
|
||||||
|
* Large cursor support
|
||||||
|
* Visual activation TODO: speed
|
||||||
|
* Copyright (c) 2000 Rik Hemsley <rik@kde.org>
|
||||||
|
*
|
||||||
|
* General/Advanced tabs
|
||||||
|
* Copyright (c) 2000 Brad Hughes <bhughes@trolltech.com>
|
||||||
|
*
|
||||||
|
* redesign for KDE 2.2
|
||||||
|
* Copyright (c) 2001 Ralf Nolden <nolden@kde.org>
|
||||||
|
*
|
||||||
|
* Logitech mouse support
|
||||||
|
* Copyright (C) 2004 Brad Hards <bradh@frogmouth.net>
|
||||||
|
*
|
||||||
|
* Requires the Qt widget libraries, available at no cost at
|
||||||
|
* http://www.troll.no/
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mousesettings.h"
|
||||||
|
|
||||||
|
#include <QX11Info>
|
||||||
|
#include <kconfiggroup.h>
|
||||||
|
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
void MouseSettings::load(KConfig *config)
|
||||||
|
{
|
||||||
|
int accel_num = 0;
|
||||||
|
int accel_den = 0;
|
||||||
|
int threshold = 0;
|
||||||
|
double accel = 0.0;
|
||||||
|
XGetPointerControl( QX11Info::display(),
|
||||||
|
&accel_num, &accel_den, &threshold );
|
||||||
|
accel = float(accel_num) / float(accel_den);
|
||||||
|
|
||||||
|
// get settings from X server
|
||||||
|
int h = RIGHT_HANDED;
|
||||||
|
unsigned char map[20];
|
||||||
|
num_buttons = XGetPointerMapping(QX11Info::display(), map, 20);
|
||||||
|
|
||||||
|
handedEnabled = true;
|
||||||
|
|
||||||
|
// ## keep this in sync with KGlobalSettings::mouseSettings
|
||||||
|
if( num_buttons == 1 )
|
||||||
|
{
|
||||||
|
/* disable button remapping */
|
||||||
|
handedEnabled = false;
|
||||||
|
}
|
||||||
|
else if( num_buttons == 2 )
|
||||||
|
{
|
||||||
|
if ( (int)map[0] == 1 && (int)map[1] == 2 )
|
||||||
|
h = RIGHT_HANDED;
|
||||||
|
else if ( (int)map[0] == 2 && (int)map[1] == 1 )
|
||||||
|
h = LEFT_HANDED;
|
||||||
|
else
|
||||||
|
/* custom button setup: disable button remapping */
|
||||||
|
handedEnabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
middle_button = (int)map[1];
|
||||||
|
if ( (int)map[0] == 1 && (int)map[2] == 3 )
|
||||||
|
h = RIGHT_HANDED;
|
||||||
|
else if ( (int)map[0] == 3 && (int)map[2] == 1 )
|
||||||
|
h = LEFT_HANDED;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* custom button setup: disable button remapping */
|
||||||
|
handedEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KConfigGroup group = config->group("Mouse");
|
||||||
|
double a = group.readEntry("Acceleration",-1.0);
|
||||||
|
if (a == -1)
|
||||||
|
accelRate = accel;
|
||||||
|
else
|
||||||
|
accelRate = a;
|
||||||
|
|
||||||
|
int t = group.readEntry("Threshold",-1);
|
||||||
|
if (t == -1)
|
||||||
|
thresholdMove = threshold;
|
||||||
|
else
|
||||||
|
thresholdMove = t;
|
||||||
|
|
||||||
|
QString key = group.readEntry("MouseButtonMapping");
|
||||||
|
if (key == "RightHanded")
|
||||||
|
handed = RIGHT_HANDED;
|
||||||
|
else if (key == "LeftHanded")
|
||||||
|
handed = LEFT_HANDED;
|
||||||
|
#warning was key == NULL how was this working? is key.isNull() what the coder meant?
|
||||||
|
else if (key.isNull())
|
||||||
|
handed = h;
|
||||||
|
reverseScrollPolarity = group.readEntry( "ReverseScrollPolarity", false);
|
||||||
|
m_handedNeedsApply = false;
|
||||||
|
|
||||||
|
// SC/DC/AutoSelect/ChangeCursor
|
||||||
|
group = config->group("KDE");
|
||||||
|
doubleClickInterval = group.readEntry("DoubleClickInterval", 400);
|
||||||
|
dragStartTime = group.readEntry("StartDragTime", 500);
|
||||||
|
dragStartDist = group.readEntry("StartDragDist", 4);
|
||||||
|
wheelScrollLines = group.readEntry("WheelScrollLines", 3);
|
||||||
|
|
||||||
|
singleClick = group.readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK);
|
||||||
|
autoSelectDelay = group.readEntry("AutoSelectDelay", KDE_DEFAULT_AUTOSELECTDELAY);
|
||||||
|
changeCursor = group.readEntry("ChangeCursor", KDE_DEFAULT_CHANGECURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseSettings::apply(bool force)
|
||||||
|
{
|
||||||
|
XChangePointerControl( QX11Info::display(),
|
||||||
|
true, true, int(qRound(accelRate*10)), 10, thresholdMove);
|
||||||
|
|
||||||
|
// 256 might seems extreme, but X has already been known to return 32,
|
||||||
|
// and we don't want to truncate things. Xlib limits the table to 256 bytes,
|
||||||
|
// so it's a good uper bound..
|
||||||
|
unsigned char map[256];
|
||||||
|
::memset(map, 0, 256 * sizeof(unsigned char));
|
||||||
|
num_buttons = XGetPointerMapping(QX11Info::display(), map, 256);
|
||||||
|
|
||||||
|
int remap=(num_buttons>=1);
|
||||||
|
if (handedEnabled && (m_handedNeedsApply || force)) {
|
||||||
|
if( num_buttons == 1 )
|
||||||
|
{
|
||||||
|
map[0] = (unsigned char) 1;
|
||||||
|
}
|
||||||
|
else if( num_buttons == 2 )
|
||||||
|
{
|
||||||
|
if (handed == RIGHT_HANDED)
|
||||||
|
{
|
||||||
|
map[0] = (unsigned char) 1;
|
||||||
|
map[1] = (unsigned char) 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map[0] = (unsigned char) 3;
|
||||||
|
map[1] = (unsigned char) 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // 3 buttons and more
|
||||||
|
{
|
||||||
|
if (handed == RIGHT_HANDED)
|
||||||
|
{
|
||||||
|
map[0] = (unsigned char) 1;
|
||||||
|
map[1] = (unsigned char) middle_button;
|
||||||
|
map[2] = (unsigned char) 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map[0] = (unsigned char) 3;
|
||||||
|
map[1] = (unsigned char) middle_button;
|
||||||
|
map[2] = (unsigned char) 1;
|
||||||
|
}
|
||||||
|
if( num_buttons >= 5 )
|
||||||
|
{
|
||||||
|
// Apps seem to expect logical buttons 4,5 are the vertical wheel.
|
||||||
|
// With mice with more than 3 buttons (not including wheel) the physical
|
||||||
|
// buttons mapped to logical 4,5 may not be physical 4,5 , so keep
|
||||||
|
// this mapping, only possibly reversing them.
|
||||||
|
int pos;
|
||||||
|
for( pos = 0; pos < num_buttons; ++pos )
|
||||||
|
if( map[pos] == 4 || map[pos] == 5 )
|
||||||
|
break;
|
||||||
|
if( pos < num_buttons - 1 )
|
||||||
|
{
|
||||||
|
map[pos] = reverseScrollPolarity ? (unsigned char) 5 : (unsigned char) 4;
|
||||||
|
map[pos+1] = reverseScrollPolarity ? (unsigned char) 4 : (unsigned char) 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int retval;
|
||||||
|
if (remap)
|
||||||
|
while ((retval=XSetPointerMapping(QX11Info::display(), map,
|
||||||
|
num_buttons)) == MappingBusy)
|
||||||
|
/* keep trying until the pointer is free */
|
||||||
|
{ };
|
||||||
|
m_handedNeedsApply = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This iterates through the various Logitech mice, if we have support.
|
||||||
|
#ifdef HAVE_LIBUSB
|
||||||
|
Q_FOREACH( LogitechMouse *logitechMouse, logitechMouseList ) {
|
||||||
|
logitechMouse->applyChanges();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseSettings::save(KConfig *config)
|
||||||
|
{
|
||||||
|
KConfigGroup group = config->group("Mouse");
|
||||||
|
group.writeEntry("Acceleration",accelRate);
|
||||||
|
group.writeEntry("Threshold",thresholdMove);
|
||||||
|
if (handed == RIGHT_HANDED)
|
||||||
|
group.writeEntry("MouseButtonMapping",QString("RightHanded"));
|
||||||
|
else
|
||||||
|
group.writeEntry("MouseButtonMapping",QString("LeftHanded"));
|
||||||
|
group.writeEntry( "ReverseScrollPolarity", reverseScrollPolarity );
|
||||||
|
|
||||||
|
group = config->group("KDE");
|
||||||
|
group.writeEntry("DoubleClickInterval", doubleClickInterval, KConfig::Persistent|KConfig::Global);
|
||||||
|
group.writeEntry("StartDragTime", dragStartTime, KConfig::Persistent|KConfig::Global);
|
||||||
|
group.writeEntry("StartDragDist", dragStartDist, KConfig::Persistent|KConfig::Global);
|
||||||
|
group.writeEntry("WheelScrollLines", wheelScrollLines, KConfig::Persistent|KConfig::Global);
|
||||||
|
group.writeEntry("SingleClick", singleClick, KConfig::Persistent|KConfig::Global);
|
||||||
|
group.writeEntry("AutoSelectDelay", autoSelectDelay, KConfig::Persistent|KConfig::Global);
|
||||||
|
group.writeEntry("ChangeCursor", changeCursor,KConfig::Persistent|KConfig::Global);
|
||||||
|
// This iterates through the various Logitech mice, if we have support.
|
||||||
|
#ifdef HAVE_LIBUSB
|
||||||
|
Q_FOREACH( LogitechMouse *logitechMouse, logitechMouseList ) {
|
||||||
|
logitechMouse->save(config);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
config->sync();
|
||||||
|
KGlobalSettings::self()->emitChange(KGlobalSettings::MouseChanged);
|
||||||
|
}
|
75
kcontrol/input/mousesettings.h
Normal file
75
kcontrol/input/mousesettings.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* mousesettings.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca
|
||||||
|
*
|
||||||
|
* Layout management, enhancements:
|
||||||
|
* Copyright (c) 1999 Dirk A. Mueller <dmuell@gmx.net>
|
||||||
|
*
|
||||||
|
* SC/DC/AutoSelect/ChangeCursor:
|
||||||
|
* Copyright (c) 2000 David Faure <faure@kde.org>
|
||||||
|
*
|
||||||
|
* Requires the Qt widget libraries, available at no cost at
|
||||||
|
* http://www.troll.no/
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __MOUSESETTINGS_H__
|
||||||
|
#define __MOUSESETTINGS_H__
|
||||||
|
|
||||||
|
#include <kconfig.h>
|
||||||
|
#include <kglobalsettings.h>
|
||||||
|
|
||||||
|
#include <config-workspace.h>
|
||||||
|
#include <config-kcontrol-input.h>
|
||||||
|
#ifdef HAVE_LIBUSB
|
||||||
|
#include "logitechmouse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RIGHT_HANDED 0
|
||||||
|
#define LEFT_HANDED 1
|
||||||
|
|
||||||
|
class MouseSettings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void save(KConfig *);
|
||||||
|
void load(KConfig *);
|
||||||
|
void apply(bool force=false);
|
||||||
|
public:
|
||||||
|
int num_buttons;
|
||||||
|
int middle_button;
|
||||||
|
bool handedEnabled;
|
||||||
|
bool m_handedNeedsApply;
|
||||||
|
int handed;
|
||||||
|
double accelRate;
|
||||||
|
int thresholdMove;
|
||||||
|
int doubleClickInterval;
|
||||||
|
int dragStartTime;
|
||||||
|
int dragStartDist;
|
||||||
|
bool singleClick;
|
||||||
|
int autoSelectDelay;
|
||||||
|
bool changeCursor;
|
||||||
|
int wheelScrollLines;
|
||||||
|
bool reverseScrollPolarity;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUSB
|
||||||
|
QList <LogitechMouse*> logitechMouseList;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -29,3 +29,22 @@ install(
|
||||||
FILES keyboard_new.desktop
|
FILES keyboard_new.desktop
|
||||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/solid/actions
|
DESTINATION ${KDE4_DATA_INSTALL_DIR}/solid/actions
|
||||||
)
|
)
|
||||||
|
|
||||||
|
########### next target ###############
|
||||||
|
|
||||||
|
add_executable(kkeyboard kkeyboard.cpp)
|
||||||
|
target_link_libraries(kkeyboard
|
||||||
|
KDE4::kdeui
|
||||||
|
${X11_LIBRARIES}
|
||||||
|
${X11_Xkbfile_LIB}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
TARGETS kkeyboard
|
||||||
|
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES kkeyboard.desktop
|
||||||
|
DESTINATION ${KDE4_AUTOSTART_INSTALL_DIR}
|
||||||
|
)
|
||||||
|
|
|
@ -2,13 +2,11 @@
|
||||||
Exec=kcmshell4 kcm_keyboard
|
Exec=kcmshell4 kcm_keyboard
|
||||||
Icon=preferences-desktop-keyboard
|
Icon=preferences-desktop-keyboard
|
||||||
Type=Service
|
Type=Service
|
||||||
X-KDE-ServiceTypes=KCModule,KCModuleInit
|
X-KDE-ServiceTypes=KCModule
|
||||||
X-DocPath=kcontrol/keyboard/index.html
|
X-DocPath=kcontrol/keyboard/index.html
|
||||||
Categories=Qt;KDE;X-KDE-settings-hardware;
|
Categories=Qt;KDE;X-KDE-settings-hardware;
|
||||||
|
|
||||||
X-KDE-Library=kcm_keyboard
|
X-KDE-Library=kcm_keyboard
|
||||||
X-KDE-Init-Symbol=kcminit_keyboard
|
|
||||||
X-KDE-Init-Phase=0
|
|
||||||
X-KDE-ParentApp=kcontrol
|
X-KDE-ParentApp=kcontrol
|
||||||
|
|
||||||
X-KDE-System-Settings-Parent-Category=input-devices
|
X-KDE-System-Settings-Parent-Category=input-devices
|
||||||
|
|
|
@ -19,11 +19,9 @@
|
||||||
#include "keyboardconfig.h"
|
#include "keyboardconfig.h"
|
||||||
#include "keyboardlayoutdialog.h"
|
#include "keyboardlayoutdialog.h"
|
||||||
#include "keyboardoptionsdialog.h"
|
#include "keyboardoptionsdialog.h"
|
||||||
|
#include "keyboardconfig_common.h"
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QX11Info>
|
|
||||||
#include <kconfiggroup.h>
|
|
||||||
#include <kkeyboardlayout.h>
|
|
||||||
#include <kstandarddirs.h>
|
#include <kstandarddirs.h>
|
||||||
#include <kicon.h>
|
#include <kicon.h>
|
||||||
#include <klocale.h>
|
#include <klocale.h>
|
||||||
|
@ -33,41 +31,6 @@
|
||||||
#include <kpluginloader.h>
|
#include <kpluginloader.h>
|
||||||
#include <kdebug.h>
|
#include <kdebug.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/XKBlib.h>
|
|
||||||
|
|
||||||
static const float s_defaultrepeatdelay = 660.0;
|
|
||||||
static const float s_defaultrepeatrate = 25.0;
|
|
||||||
|
|
||||||
static QList<KKeyboardType> kLayoutsFromConfig()
|
|
||||||
{
|
|
||||||
KConfig kconfig("kcminputrc", KConfig::NoGlobals);
|
|
||||||
KConfigGroup kconfiggroup(&kconfig, "Keyboard");
|
|
||||||
const KKeyboardType defaultlayout = KKeyboardLayout::defaultLayout();
|
|
||||||
const QByteArray layoutsmodel = kconfiggroup.readEntry("LayoutsModel", defaultlayout.model);
|
|
||||||
const QByteArray layoutsoptions = kconfiggroup.readEntry("LayoutsOptions", defaultlayout.option);
|
|
||||||
const QStringList layoutslayouts = kconfiggroup.readEntry(
|
|
||||||
"LayoutsLayouts",
|
|
||||||
QStringList() << QString::fromLatin1(defaultlayout.layout.constData(), defaultlayout.layout.size())
|
|
||||||
);
|
|
||||||
const QStringList layoutsvariants = kconfiggroup.readEntry(
|
|
||||||
"LayoutsVariants",
|
|
||||||
QStringList() << QString::fromLatin1(defaultlayout.variant.constData(), defaultlayout.variant.size())
|
|
||||||
);
|
|
||||||
QList<KKeyboardType> result;
|
|
||||||
for (int i = 0; i < layoutslayouts.size(); i++) {
|
|
||||||
KKeyboardType kkeyboardtype;
|
|
||||||
kkeyboardtype.model = layoutsmodel;
|
|
||||||
kkeyboardtype.layout = layoutslayouts.at(i).toLatin1();
|
|
||||||
if (i < layoutsvariants.size()) {
|
|
||||||
kkeyboardtype.variant = layoutsvariants.at(i).toLatin1();
|
|
||||||
}
|
|
||||||
kkeyboardtype.option = layoutsoptions;
|
|
||||||
result.append(kkeyboardtype);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void kFillTreeFromLayouts(QTreeWidget *treewidget, const QList<KKeyboardType> &layouts)
|
static void kFillTreeFromLayouts(QTreeWidget *treewidget, const QList<KKeyboardType> &layouts)
|
||||||
{
|
{
|
||||||
treewidget->clear();
|
treewidget->clear();
|
||||||
|
@ -104,46 +67,6 @@ static QList<KKeyboardType> kGetLayoutsFromTree(QTreeWidget *treewidget, const Q
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kApplyKeyboardConfig()
|
|
||||||
{
|
|
||||||
const QList<KKeyboardType> layouts = kLayoutsFromConfig();
|
|
||||||
if (layouts.size() > 0) {
|
|
||||||
KKeyboardLayout().setLayouts(layouts);
|
|
||||||
}
|
|
||||||
|
|
||||||
KConfig kconfig("kcminputrc", KConfig::NoGlobals);
|
|
||||||
KConfigGroup kconfiggroup(&kconfig, "Keyboard");
|
|
||||||
const float repeatdelay = kconfiggroup.readEntry("RepeatDelay", s_defaultrepeatdelay);
|
|
||||||
const float repeatrate = kconfiggroup.readEntry("RepeatRate", s_defaultrepeatrate);
|
|
||||||
|
|
||||||
XkbDescPtr xkbkeyboard = XkbAllocKeyboard();
|
|
||||||
if (!xkbkeyboard) {
|
|
||||||
kError() << "Failed to allocate keyboard";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Status xkbgetresult = XkbGetControls(QX11Info::display(), XkbRepeatKeysMask, xkbkeyboard);
|
|
||||||
if (xkbgetresult != Success) {
|
|
||||||
kError() << "Failed to get keyboard repeat controls";
|
|
||||||
XkbFreeKeyboard(xkbkeyboard, 0, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
xkbkeyboard->ctrls->repeat_delay = repeatdelay;
|
|
||||||
xkbkeyboard->ctrls->repeat_interval = qFloor(1000 / repeatrate + 0.5);
|
|
||||||
const Bool xkbsetresult = XkbSetControls(QX11Info::display(), XkbRepeatKeysMask, xkbkeyboard);
|
|
||||||
if (xkbsetresult != True) {
|
|
||||||
kError() << "Failed to set keyboard repeat controls";
|
|
||||||
}
|
|
||||||
XkbFreeKeyboard(xkbkeyboard, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
Q_DECL_EXPORT void kcminit_keyboard()
|
|
||||||
{
|
|
||||||
kApplyKeyboardConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
K_PLUGIN_FACTORY(KCMKeyboardFactory, registerPlugin<KCMKeyboard>();)
|
K_PLUGIN_FACTORY(KCMKeyboardFactory, registerPlugin<KCMKeyboard>();)
|
||||||
K_EXPORT_PLUGIN(KCMKeyboardFactory("kcmkeyboard", "kcm_keyboard"))
|
K_EXPORT_PLUGIN(KCMKeyboardFactory("kcmkeyboard", "kcm_keyboard"))
|
||||||
|
|
||||||
|
|
97
kcontrol/keyboard/keyboardconfig_common.h
Normal file
97
kcontrol/keyboard/keyboardconfig_common.h
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/* This file is part of the KDE project
|
||||||
|
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEYBOARDCONFIG_COMMON_H
|
||||||
|
#define KEYBOARDCONFIG_COMMON_H
|
||||||
|
|
||||||
|
#include <QX11Info>
|
||||||
|
#include <qmath.h>
|
||||||
|
#include <kkeyboardlayout.h>
|
||||||
|
#include <kconfig.h>
|
||||||
|
#include <kconfiggroup.h>
|
||||||
|
#include <kdebug.h>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
|
static const float s_defaultrepeatdelay = 660.0;
|
||||||
|
static const float s_defaultrepeatrate = 25.0;
|
||||||
|
|
||||||
|
static QList<KKeyboardType> kLayoutsFromConfig()
|
||||||
|
{
|
||||||
|
KConfig kconfig("kcminputrc", KConfig::NoGlobals);
|
||||||
|
KConfigGroup kconfiggroup(&kconfig, "Keyboard");
|
||||||
|
const KKeyboardType defaultlayout = KKeyboardLayout::defaultLayout();
|
||||||
|
const QByteArray layoutsmodel = kconfiggroup.readEntry("LayoutsModel", defaultlayout.model);
|
||||||
|
const QByteArray layoutsoptions = kconfiggroup.readEntry("LayoutsOptions", defaultlayout.option);
|
||||||
|
const QStringList layoutslayouts = kconfiggroup.readEntry(
|
||||||
|
"LayoutsLayouts",
|
||||||
|
QStringList() << QString::fromLatin1(defaultlayout.layout.constData(), defaultlayout.layout.size())
|
||||||
|
);
|
||||||
|
const QStringList layoutsvariants = kconfiggroup.readEntry(
|
||||||
|
"LayoutsVariants",
|
||||||
|
QStringList() << QString::fromLatin1(defaultlayout.variant.constData(), defaultlayout.variant.size())
|
||||||
|
);
|
||||||
|
QList<KKeyboardType> result;
|
||||||
|
for (int i = 0; i < layoutslayouts.size(); i++) {
|
||||||
|
KKeyboardType kkeyboardtype;
|
||||||
|
kkeyboardtype.model = layoutsmodel;
|
||||||
|
kkeyboardtype.layout = layoutslayouts.at(i).toLatin1();
|
||||||
|
if (i < layoutsvariants.size()) {
|
||||||
|
kkeyboardtype.variant = layoutsvariants.at(i).toLatin1();
|
||||||
|
}
|
||||||
|
kkeyboardtype.option = layoutsoptions;
|
||||||
|
result.append(kkeyboardtype);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kApplyKeyboardConfig()
|
||||||
|
{
|
||||||
|
const QList<KKeyboardType> layouts = kLayoutsFromConfig();
|
||||||
|
if (layouts.size() > 0) {
|
||||||
|
KKeyboardLayout().setLayouts(layouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
KConfig kconfig("kcminputrc", KConfig::NoGlobals);
|
||||||
|
KConfigGroup kconfiggroup(&kconfig, "Keyboard");
|
||||||
|
const float repeatdelay = kconfiggroup.readEntry("RepeatDelay", s_defaultrepeatdelay);
|
||||||
|
const float repeatrate = kconfiggroup.readEntry("RepeatRate", s_defaultrepeatrate);
|
||||||
|
|
||||||
|
XkbDescPtr xkbkeyboard = XkbAllocKeyboard();
|
||||||
|
if (!xkbkeyboard) {
|
||||||
|
kError() << "Failed to allocate keyboard";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Status xkbgetresult = XkbGetControls(QX11Info::display(), XkbRepeatKeysMask, xkbkeyboard);
|
||||||
|
if (xkbgetresult != Success) {
|
||||||
|
kError() << "Failed to get keyboard repeat controls";
|
||||||
|
XkbFreeKeyboard(xkbkeyboard, 0, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xkbkeyboard->ctrls->repeat_delay = repeatdelay;
|
||||||
|
xkbkeyboard->ctrls->repeat_interval = qFloor(1000 / repeatrate + 0.5);
|
||||||
|
const Bool xkbsetresult = XkbSetControls(QX11Info::display(), XkbRepeatKeysMask, xkbkeyboard);
|
||||||
|
if (xkbsetresult != True) {
|
||||||
|
kError() << "Failed to set keyboard repeat controls";
|
||||||
|
}
|
||||||
|
XkbFreeKeyboard(xkbkeyboard, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // KEYBOARDCONFIG_COMMON_H
|
31
kcontrol/keyboard/kkeyboard.cpp
Normal file
31
kcontrol/keyboard/kkeyboard.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* This file is part of the KDE project
|
||||||
|
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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 <QCoreApplication>
|
||||||
|
#include <KDebug>
|
||||||
|
|
||||||
|
#include "keyboardconfig_common.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// application instance for events processing
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
kApplyKeyboardConfig();
|
||||||
|
return 0;
|
||||||
|
}
|
9
kcontrol/keyboard/kkeyboard.desktop
Normal file
9
kcontrol/keyboard/kkeyboard.desktop
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Service
|
||||||
|
Name=KDE Keyboard
|
||||||
|
Exec=kkeyboard
|
||||||
|
Icon=preferences-desktop-keyboard
|
||||||
|
StartupNotify=false
|
||||||
|
OnlyShowIn=KDE;
|
||||||
|
X-KDE-autostart-phase=0
|
||||||
|
X-DocPath=kcontrol/keyboard/index.html
|
|
@ -114,7 +114,6 @@ PlasmaApp::PlasmaApp()
|
||||||
m_panelHidden(0),
|
m_panelHidden(0),
|
||||||
m_phase(0),
|
m_phase(0),
|
||||||
m_klauncher(nullptr),
|
m_klauncher(nullptr),
|
||||||
m_kcminit(nullptr),
|
|
||||||
m_wmproc(nullptr),
|
m_wmproc(nullptr),
|
||||||
m_startupsuspend(0),
|
m_startupsuspend(0),
|
||||||
m_dialogActive(false),
|
m_dialogActive(false),
|
||||||
|
@ -181,13 +180,6 @@ PlasmaApp::PlasmaApp()
|
||||||
QDBusConnection::sessionBus(),
|
QDBusConnection::sessionBus(),
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
m_kcminit = new QDBusInterface(
|
|
||||||
QLatin1String("org.kde.kcminit"),
|
|
||||||
QLatin1String("/kcminit"),
|
|
||||||
QLatin1String("org.kde.KCMInit"),
|
|
||||||
QDBusConnection::sessionBus(),
|
|
||||||
this
|
|
||||||
);
|
|
||||||
const bool failsafe = (qgetenv("KDE_FAILSAFE").toInt() == 1);
|
const bool failsafe = (qgetenv("KDE_FAILSAFE").toInt() == 1);
|
||||||
if (!failsafe) {
|
if (!failsafe) {
|
||||||
m_sessionManager = true;
|
m_sessionManager = true;
|
||||||
|
@ -1174,13 +1166,11 @@ void PlasmaApp::nextPhase()
|
||||||
sessionInterface->startService(kdedInterface);
|
sessionInterface->startService(kdedInterface);
|
||||||
}
|
}
|
||||||
m_klauncher->asyncCall("autoStart", int(0));
|
m_klauncher->asyncCall("autoStart", int(0));
|
||||||
m_kcminit->asyncCall("runPhase1");
|
|
||||||
QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase()));
|
QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
m_klauncher->asyncCall("autoStart", int(1));
|
m_klauncher->asyncCall("autoStart", int(1));
|
||||||
m_kcminit->asyncCall("runPhase2");
|
|
||||||
QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase()));
|
QTimer::singleShot(s_phasedelay, this, SLOT(nextPhase()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,6 @@ private:
|
||||||
QHash<int, QWeakPointer<ControllerWindow> > m_widgetExplorers;
|
QHash<int, QWeakPointer<ControllerWindow> > m_widgetExplorers;
|
||||||
int m_phase;
|
int m_phase;
|
||||||
QDBusInterface* m_klauncher;
|
QDBusInterface* m_klauncher;
|
||||||
QDBusInterface* m_kcminit;
|
|
||||||
QProcess* m_wmproc;
|
QProcess* m_wmproc;
|
||||||
int m_startupsuspend;
|
int m_startupsuspend;
|
||||||
bool m_dialogActive;
|
bool m_dialogActive;
|
||||||
|
|
|
@ -116,16 +116,6 @@ dbus-update-activation-environment DISPLAY XAUTHORITY XDG_CURRENT_DESKTOP \
|
||||||
# update it when that happens
|
# update it when that happens
|
||||||
kbuildsycoca4
|
kbuildsycoca4
|
||||||
|
|
||||||
# Start kcminit_startup
|
|
||||||
kcminit_startup
|
|
||||||
kcminit_result=$?
|
|
||||||
if test $? -ne 0; then
|
|
||||||
# Startup error
|
|
||||||
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 plasma-desktop
|
# finally, give the session control to plasma-desktop
|
||||||
plasma-desktop
|
plasma-desktop
|
||||||
plasma_result=$?
|
plasma_result=$?
|
||||||
|
|
Loading…
Add table
Reference in a new issue