kwin/kcmkwin/kwinoptions/mouse.cpp

572 lines
18 KiB
C++

/*
*
* Copyright (c) 1998 Matthias Ettrich <ettrich@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 "mouse.h"
#include <QLabel>
#include <KComboBox>
#include <QLayout>
#include <QSizePolicy>
#include <QBitmap>
#include <QGroupBox>
#include <QPixmap>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <QDebug>
#include <kcolorscheme.h>
#include <kseparator.h>
#include <QtDBus/QtDBus>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdlib.h>
#include "mouse.moc"
namespace
{
char const * const cnf_Max[] = {
"MaximizeButtonLeftClickCommand",
"MaximizeButtonMiddleClickCommand",
"MaximizeButtonRightClickCommand",
};
char const * const tbl_Max[] = {
"Maximize",
"Maximize (vertical only)",
"Maximize (horizontal only)",
""
};
QPixmap maxButtonPixmaps[3];
void createMaxButtonPixmaps()
{
char const * maxButtonXpms[][3 + 13] = {
{
0, 0, 0,
"...............",
".......#.......",
"......###......",
".....#####.....",
"..#....#....#..",
".##....#....##.",
"###############",
".##....#....##.",
"..#....#....#..",
".....#####.....",
"......###......",
".......#.......",
"..............."
},
{
0, 0, 0,
"...............",
".......#.......",
"......###......",
".....#####.....",
".......#.......",
".......#.......",
".......#.......",
".......#.......",
".......#.......",
".....#####.....",
"......###......",
".......#.......",
"..............."
},
{
0, 0, 0,
"...............",
"...............",
"...............",
"...............",
"..#.........#..",
".##.........##.",
"###############",
".##.........##.",
"..#.........#..",
"...............",
"...............",
"...............",
"..............."
},
};
QByteArray baseColor(". c " + KColorScheme(QPalette::Active, KColorScheme::View).background().color().name().toAscii());
QByteArray textColor("# c " + KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name().toAscii());
for (int t = 0; t < 3; ++t) {
maxButtonXpms[t][0] = "15 13 2 1";
maxButtonXpms[t][1] = baseColor.constData();
maxButtonXpms[t][2] = textColor.constData();
maxButtonPixmaps[t] = QPixmap(maxButtonXpms[t]);
maxButtonPixmaps[t].setMask(maxButtonPixmaps[t].createHeuristicMask());
}
}
} // namespace
KWinMouseConfigForm::KWinMouseConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(parent);
}
KWinActionsConfigForm::KWinActionsConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(parent);
}
void KTitleBarActionsConfig::paletteChanged()
{
createMaxButtonPixmaps();
for (int i=0; i<3; ++i) {
m_ui->leftClickMaximizeButton->setItemIcon(i, maxButtonPixmaps[i]);
m_ui->middleClickMaximizeButton->setItemIcon(i, maxButtonPixmaps[i]);
m_ui->rightClickMaximizeButton->setItemIcon(i, maxButtonPixmaps[i]);
}
}
KTitleBarActionsConfig::KTitleBarActionsConfig(bool _standAlone, KConfig *_config, QWidget * parent)
: KCModule(parent), config(_config), standAlone(_standAlone)
, m_ui(new KWinMouseConfigForm(this))
{
// create the items for the maximize button actions
createMaxButtonPixmaps();
for (int i=0; i<3; ++i) {
m_ui->leftClickMaximizeButton->addItem(maxButtonPixmaps[i], QString());
m_ui->middleClickMaximizeButton->addItem(maxButtonPixmaps[i], QString());
m_ui->rightClickMaximizeButton->addItem(maxButtonPixmaps[i], QString());
}
createMaximizeButtonTooltips(m_ui->leftClickMaximizeButton);
createMaximizeButtonTooltips(m_ui->middleClickMaximizeButton);
createMaximizeButtonTooltips(m_ui->rightClickMaximizeButton);
connect(m_ui->coTiDbl, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coTiAct1, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coTiAct2, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coTiAct3, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coTiAct4, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coTiInAct1, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coTiInAct2, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coTiInAct3, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->leftClickMaximizeButton, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->middleClickMaximizeButton, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->rightClickMaximizeButton, SIGNAL(activated(int)), SLOT(changed()));
load();
}
KTitleBarActionsConfig::~KTitleBarActionsConfig()
{
if (standAlone)
delete config;
}
void KTitleBarActionsConfig::createMaximizeButtonTooltips(KComboBox *combo)
{
combo->setItemData(0, i18n("Maximize"), Qt::ToolTipRole);
combo->setItemData(1, i18n("Maximize (vertical only)"), Qt::ToolTipRole);
combo->setItemData(2, i18n("Maximize (horizontal only)"), Qt::ToolTipRole);
}
// do NOT change the texts below, they are written to config file
// and are not shown in the GUI
// they have to match the order of items in GUI elements though
const char* const tbl_TiDbl[] = {
"Maximize",
"Maximize (vertical only)",
"Maximize (horizontal only)",
"Minimize",
"Shade",
"Lower",
"Close",
"OnAllDesktops",
"Nothing",
""
};
const char* const tbl_TiAc[] = {
"Raise",
"Lower",
"Toggle raise and lower",
"Minimize",
"Shade",
"Close",
"Operations menu",
"Start window tab drag",
"Nothing",
""
};
const char* const tbl_TiInAc[] = {
"Activate and raise",
"Activate and lower",
"Activate",
"Raise",
"Lower",
"Toggle raise and lower",
"Minimize",
"Shade",
"Close",
"Operations menu",
"Start window tab drag",
"Nothing",
""
};
const char* const tbl_Win[] = {
"Activate, raise and pass click",
"Activate and pass click",
"Activate",
"Activate and raise",
""
};
const char* const tbl_WinWheel[] = {
"Scroll",
"Activate and scroll",
"Activate, raise and scroll",
""
};
const char* const tbl_AllKey[] = {
"Meta",
"Alt",
""
};
const char* const tbl_All[] = {
"Move",
"Activate, raise and move",
"Toggle raise and lower",
"Resize",
"Raise",
"Lower",
"Minimize",
"Decrease Opacity",
"Increase Opacity",
"Nothing",
""
};
const char* const tbl_TiWAc[] = {
"Raise/Lower",
"Shade/Unshade",
"Maximize/Restore",
"Above/Below",
"Previous/Next Desktop",
"Change Opacity",
"Switch to Window Tab to the Left/Right",
"Nothing",
""
};
const char* const tbl_AllW[] = {
"Raise/Lower",
"Shade/Unshade",
"Maximize/Restore",
"Above/Below",
"Previous/Next Desktop",
"Change Opacity",
"Switch to Window Tab to the Left/Right",
"Nothing",
""
};
static const char* tbl_num_lookup(const char* const arr[], int pos)
{
for (int i = 0;
arr[ i ][ 0 ] != '\0' && pos >= 0;
++i) {
if (pos == 0)
return arr[ i ];
--pos;
}
abort(); // should never happen this way
}
static int tbl_txt_lookup(const char* const arr[], const char* txt)
{
int pos = 0;
for (int i = 0;
arr[ i ][ 0 ] != '\0';
++i) {
if (qstricmp(txt, arr[ i ]) == 0)
return pos;
++pos;
}
return 0;
}
void KTitleBarActionsConfig::setComboText(KComboBox* combo, const char*txt)
{
if (combo == m_ui->coTiDbl)
combo->setCurrentIndex(tbl_txt_lookup(tbl_TiDbl, txt));
else if (combo == m_ui->coTiAct1 || combo == m_ui->coTiAct2 || combo == m_ui->coTiAct3)
combo->setCurrentIndex(tbl_txt_lookup(tbl_TiAc, txt));
else if (combo == m_ui->coTiInAct1 || combo == m_ui->coTiInAct2 || combo == m_ui->coTiInAct3)
combo->setCurrentIndex(tbl_txt_lookup(tbl_TiInAc, txt));
else if (combo == m_ui->coTiAct4)
combo->setCurrentIndex(tbl_txt_lookup(tbl_TiWAc, txt));
else if (combo == m_ui->leftClickMaximizeButton ||
combo == m_ui->middleClickMaximizeButton ||
combo == m_ui->rightClickMaximizeButton) {
combo->setCurrentIndex(tbl_txt_lookup(tbl_Max, txt));
} else
abort();
}
const char* KTitleBarActionsConfig::functionTiDbl(int i)
{
return tbl_num_lookup(tbl_TiDbl, i);
}
const char* KTitleBarActionsConfig::functionTiAc(int i)
{
return tbl_num_lookup(tbl_TiAc, i);
}
const char* KTitleBarActionsConfig::functionTiInAc(int i)
{
return tbl_num_lookup(tbl_TiInAc, i);
}
const char* KTitleBarActionsConfig::functionTiWAc(int i)
{
return tbl_num_lookup(tbl_TiWAc, i);
}
const char* KTitleBarActionsConfig::functionMax(int i)
{
return tbl_num_lookup(tbl_Max, i);
}
void KTitleBarActionsConfig::showEvent(QShowEvent *ev)
{
if (!standAlone) {
// Workaround KCModule::showEvent() calling load(), see bug 163817
QWidget::showEvent(ev);
return;
}
KCModule::showEvent(ev);
}
void KTitleBarActionsConfig::changeEvent(QEvent *ev)
{
if (ev->type() == QEvent::PaletteChange) {
paletteChanged();
}
ev->accept();
}
void KTitleBarActionsConfig::load()
{
KConfigGroup windowsConfig(config, "Windows");
setComboText(m_ui->coTiDbl, windowsConfig.readEntry("TitlebarDoubleClickCommand", "Maximize").toAscii());
setComboText(m_ui->leftClickMaximizeButton, windowsConfig.readEntry(cnf_Max[0], tbl_Max[0]).toAscii());
setComboText(m_ui->middleClickMaximizeButton, windowsConfig.readEntry(cnf_Max[1], tbl_Max[1]).toAscii());
setComboText(m_ui->rightClickMaximizeButton, windowsConfig.readEntry(cnf_Max[2], tbl_Max[2]).toAscii());
KConfigGroup cg(config, "MouseBindings");
setComboText(m_ui->coTiAct1, cg.readEntry("CommandActiveTitlebar1", "Raise").toAscii());
setComboText(m_ui->coTiAct2, cg.readEntry("CommandActiveTitlebar2", "Start Window Tab Drag").toAscii());
setComboText(m_ui->coTiAct3, cg.readEntry("CommandActiveTitlebar3", "Operations menu").toAscii());
setComboText(m_ui->coTiAct4, cg.readEntry("CommandTitlebarWheel", "Switch to Window Tab to the Left/Right").toAscii());
setComboText(m_ui->coTiInAct1, cg.readEntry("CommandInactiveTitlebar1", "Activate and raise").toAscii());
setComboText(m_ui->coTiInAct2, cg.readEntry("CommandInactiveTitlebar2", "Start Window Tab Drag").toAscii());
setComboText(m_ui->coTiInAct3, cg.readEntry("CommandInactiveTitlebar3", "Operations menu").toAscii());
}
void KTitleBarActionsConfig::save()
{
KConfigGroup windowsConfig(config, "Windows");
windowsConfig.writeEntry("TitlebarDoubleClickCommand", functionTiDbl(m_ui->coTiDbl->currentIndex()));
windowsConfig.writeEntry(cnf_Max[0], functionMax(m_ui->leftClickMaximizeButton->currentIndex()));
windowsConfig.writeEntry(cnf_Max[1], functionMax(m_ui->middleClickMaximizeButton->currentIndex()));
windowsConfig.writeEntry(cnf_Max[2], functionMax(m_ui->rightClickMaximizeButton->currentIndex()));
KConfigGroup cg(config, "MouseBindings");
cg.writeEntry("CommandActiveTitlebar1", functionTiAc(m_ui->coTiAct1->currentIndex()));
cg.writeEntry("CommandActiveTitlebar2", functionTiAc(m_ui->coTiAct2->currentIndex()));
cg.writeEntry("CommandActiveTitlebar3", functionTiAc(m_ui->coTiAct3->currentIndex()));
cg.writeEntry("CommandInactiveTitlebar1", functionTiInAc(m_ui->coTiInAct1->currentIndex()));
cg.writeEntry("CommandTitlebarWheel", functionTiWAc(m_ui->coTiAct4->currentIndex()));
cg.writeEntry("CommandInactiveTitlebar2", functionTiInAc(m_ui->coTiInAct2->currentIndex()));
cg.writeEntry("CommandInactiveTitlebar3", functionTiInAc(m_ui->coTiInAct3->currentIndex()));
if (standAlone) {
config->sync();
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
}
void KTitleBarActionsConfig::defaults()
{
setComboText(m_ui->coTiDbl, "Shade");
setComboText(m_ui->coTiAct1, "Raise");
setComboText(m_ui->coTiAct2, "Start Window Tab Drag");
setComboText(m_ui->coTiAct3, "Operations menu");
setComboText(m_ui->coTiAct4, "Switch to Window Tab to the Left/Right");
setComboText(m_ui->coTiInAct1, "Activate and raise");
setComboText(m_ui->coTiInAct2, "Start Window Tab Drag");
setComboText(m_ui->coTiInAct3, "Operations menu");
setComboText(m_ui->leftClickMaximizeButton, tbl_Max[0]);
setComboText(m_ui->middleClickMaximizeButton, tbl_Max[1]);
setComboText(m_ui->rightClickMaximizeButton, tbl_Max[2]);
}
KWindowActionsConfig::KWindowActionsConfig(bool _standAlone, KConfig *_config, QWidget * parent)
: KCModule(parent), config(_config), standAlone(_standAlone)
, m_ui(new KWinActionsConfigForm(this))
{
connect(m_ui->coWin1, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coWin2, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coWin3, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coWinWheel, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coAllKey, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coAll1, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coAll2, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coAll3, SIGNAL(activated(int)), SLOT(changed()));
connect(m_ui->coAllW, SIGNAL(activated(int)), SLOT(changed()));
load();
}
KWindowActionsConfig::~KWindowActionsConfig()
{
if (standAlone)
delete config;
}
void KWindowActionsConfig::setComboText(KComboBox* combo, const char*txt)
{
if (combo == m_ui->coWin1 || combo == m_ui->coWin2 || combo == m_ui->coWin3)
combo->setCurrentIndex(tbl_txt_lookup(tbl_Win, txt));
else if (combo == m_ui->coWinWheel)
combo->setCurrentIndex(tbl_txt_lookup(tbl_WinWheel, txt));
else if (combo == m_ui->coAllKey)
combo->setCurrentIndex(tbl_txt_lookup(tbl_AllKey, txt));
else if (combo == m_ui->coAll1 || combo == m_ui->coAll2 || combo == m_ui->coAll3)
combo->setCurrentIndex(tbl_txt_lookup(tbl_All, txt));
else if (combo == m_ui->coAllW)
combo->setCurrentIndex(tbl_txt_lookup(tbl_AllW, txt));
else
abort();
}
const char* KWindowActionsConfig::functionWin(int i)
{
return tbl_num_lookup(tbl_Win, i);
}
const char* KWindowActionsConfig::functionWinWheel(int i)
{
return tbl_num_lookup(tbl_WinWheel, i);
}
const char* KWindowActionsConfig::functionAllKey(int i)
{
return tbl_num_lookup(tbl_AllKey, i);
}
const char* KWindowActionsConfig::functionAll(int i)
{
return tbl_num_lookup(tbl_All, i);
}
const char* KWindowActionsConfig::functionAllW(int i)
{
return tbl_num_lookup(tbl_AllW, i);
}
void KWindowActionsConfig::showEvent(QShowEvent *ev)
{
if (!standAlone) {
QWidget::showEvent(ev);
return;
}
KCModule::showEvent(ev);
}
void KWindowActionsConfig::load()
{
KConfigGroup cg(config, "MouseBindings");
setComboText(m_ui->coWin1, cg.readEntry("CommandWindow1", "Activate, raise and pass click").toAscii());
setComboText(m_ui->coWin2, cg.readEntry("CommandWindow2", "Activate and pass click").toAscii());
setComboText(m_ui->coWin3, cg.readEntry("CommandWindow3", "Activate and pass click").toAscii());
setComboText(m_ui->coWinWheel, cg.readEntry("CommandWindowWheel", "Scroll").toAscii());
setComboText(m_ui->coAllKey, cg.readEntry("CommandAllKey", "Alt").toAscii());
setComboText(m_ui->coAll1, cg.readEntry("CommandAll1", "Move").toAscii());
setComboText(m_ui->coAll2, cg.readEntry("CommandAll2", "Toggle raise and lower").toAscii());
setComboText(m_ui->coAll3, cg.readEntry("CommandAll3", "Resize").toAscii());
setComboText(m_ui->coAllW, cg.readEntry("CommandAllWheel", "Nothing").toAscii());
}
void KWindowActionsConfig::save()
{
KConfigGroup cg(config, "MouseBindings");
cg.writeEntry("CommandWindow1", functionWin(m_ui->coWin1->currentIndex()));
cg.writeEntry("CommandWindow2", functionWin(m_ui->coWin2->currentIndex()));
cg.writeEntry("CommandWindow3", functionWin(m_ui->coWin3->currentIndex()));
cg.writeEntry("CommandWindowWheel", functionWinWheel(m_ui->coWinWheel->currentIndex()));
cg.writeEntry("CommandAllKey", functionAllKey(m_ui->coAllKey->currentIndex()));
cg.writeEntry("CommandAll1", functionAll(m_ui->coAll1->currentIndex()));
cg.writeEntry("CommandAll2", functionAll(m_ui->coAll2->currentIndex()));
cg.writeEntry("CommandAll3", functionAll(m_ui->coAll3->currentIndex()));
cg.writeEntry("CommandAllWheel", functionAllW(m_ui->coAllW->currentIndex()));
if (standAlone) {
config->sync();
// Send signal to all kwin instances
QDBusMessage message =
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
QDBusConnection::sessionBus().send(message);
}
}
void KWindowActionsConfig::defaults()
{
setComboText(m_ui->coWin1, "Activate, raise and pass click");
setComboText(m_ui->coWin2, "Activate and pass click");
setComboText(m_ui->coWin3, "Activate and pass click");
setComboText(m_ui->coWinWheel, "Scroll");
setComboText(m_ui->coAllKey, "Alt");
setComboText(m_ui->coAll1, "Move");
setComboText(m_ui->coAll2, "Toggle raise and lower");
setComboText(m_ui->coAll3, "Resize");
setComboText(m_ui->coAllW, "Nothing");
}