[kdecorations] Introduce an enum for decoration buttons instead of characters
A new enum is introduced which defines all the buttons known to KWin. The defaultTitleButton methods return a list of DecorationButtons instead of a string which needs to be parsed by the decoration. The same for the actual title buttons. The reading/storing of the buttons is unchanged, that is the same characters are used and mapped to the button types.
This commit is contained in:
parent
79d36fe4e9
commit
b73d90cf78
7 changed files with 327 additions and 220 deletions
|
@ -387,187 +387,190 @@ int KCommonDecoration::buttonContainerWidth(const ButtonContainer &btnContainer,
|
|||
return w;
|
||||
}
|
||||
|
||||
void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QString& s, bool isLeft)
|
||||
void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QList<DecorationButton>& buttons, bool isLeft)
|
||||
{
|
||||
if (s.length() > 0) {
|
||||
for (int n = 0; n < s.length(); n++) {
|
||||
KCommonDecorationButton *btn = 0;
|
||||
switch(s[n].toAscii()) {
|
||||
case 'M': // Menu button
|
||||
if (!d->button[MenuButton]) {
|
||||
btn = createButton(MenuButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18nc("Button showing window actions menu", "Window Menu"));
|
||||
btn->setRealizeButtons(Qt::LeftButton | Qt::RightButton);
|
||||
connect(btn, SIGNAL(pressed()), SLOT(menuButtonPressed()));
|
||||
connect(btn, SIGNAL(released()), this, SLOT(menuButtonReleased()));
|
||||
if (buttons.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (auto button : buttons) {
|
||||
KCommonDecorationButton *btn = 0;
|
||||
switch(button) {
|
||||
case DecorationButtonMenu:
|
||||
if (!d->button[MenuButton]) {
|
||||
btn = createButton(MenuButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18nc("Button showing window actions menu", "Window Menu"));
|
||||
btn->setRealizeButtons(Qt::LeftButton | Qt::RightButton);
|
||||
connect(btn, SIGNAL(pressed()), SLOT(menuButtonPressed()));
|
||||
connect(btn, SIGNAL(released()), this, SLOT(menuButtonReleased()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[MenuButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'N': // Application Menu button
|
||||
if (!d->button[AppMenuButton]) {
|
||||
btn = createButton(AppMenuButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18nc("Button showing application menu", "Application Menu"));
|
||||
btn->setRealizeButtons(Qt::LeftButton);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(appMenuButtonPressed()), Qt::QueuedConnection);
|
||||
// Application want to show it menu
|
||||
connect(decoration(), SIGNAL(showRequest()), this, SLOT(appMenuButtonPressed()), Qt::UniqueConnection);
|
||||
// Wait for menu to become available before displaying any button
|
||||
connect(decoration(), SIGNAL(appMenuAvailable()), this, SLOT(slotAppMenuAvailable()), Qt::UniqueConnection);
|
||||
// On Kded module shutdown, hide application menu button
|
||||
connect(decoration(), SIGNAL(appMenuUnavailable()), this, SLOT(slotAppMenuUnavailable()), Qt::UniqueConnection);
|
||||
// Application menu button may need to be modified on this signal
|
||||
connect(decoration(), SIGNAL(menuHidden()), btn, SLOT(slotAppMenuHidden()), Qt::UniqueConnection);
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
d->button[AppMenuButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'S': // OnAllDesktops button
|
||||
if (!d->button[OnAllDesktopsButton]) {
|
||||
btn = createButton(OnAllDesktopsButton);
|
||||
if (!btn) break;
|
||||
const bool oad = isOnAllDesktops();
|
||||
btn->setTipText(oad ? i18n("Not on all desktops") : i18n("On all desktops"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(oad);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[OnAllDesktopsButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'H': // Help button
|
||||
if ((!d->button[HelpButton]) && providesContextHelp()) {
|
||||
btn = createButton(HelpButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18n("Help"));
|
||||
connect(btn, SIGNAL(clicked()), SLOT(showContextHelp()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[HelpButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'I': // Minimize button
|
||||
if ((!d->button[MinButton]) && isMinimizable()) {
|
||||
btn = createButton(MinButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18n("Minimize"));
|
||||
connect(btn, SIGNAL(clicked()), SLOT(minimize()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[MinButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'A': // Maximize button
|
||||
if ((!d->button[MaxButton]) && isMaximizable()) {
|
||||
btn = createButton(MaxButton);
|
||||
if (!btn) break;
|
||||
btn->setRealizeButtons(Qt::LeftButton | Qt::MidButton | Qt::RightButton);
|
||||
const bool max = maximizeMode() == MaximizeFull;
|
||||
btn->setTipText(max ? i18n("Restore") : i18n("Maximize"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(max);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotMaximize()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[MaxButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'X': // Close button
|
||||
if ((!d->button[CloseButton]) && isCloseable()) {
|
||||
btn = createButton(CloseButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18n("Close"));
|
||||
connect(btn, SIGNAL(clicked()), SLOT(closeWindow()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[CloseButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'F': // AboveButton button
|
||||
if (!d->button[AboveButton]) {
|
||||
btn = createButton(AboveButton);
|
||||
if (!btn) break;
|
||||
bool above = keepAbove();
|
||||
btn->setTipText(above ? i18n("Do not keep above others") : i18n("Keep above others"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(above);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotKeepAbove()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[AboveButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'B': // BelowButton button
|
||||
if (!d->button[BelowButton]) {
|
||||
btn = createButton(BelowButton);
|
||||
if (!btn) break;
|
||||
bool below = keepBelow();
|
||||
btn->setTipText(below ? i18n("Do not keep below others") : i18n("Keep below others"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(below);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotKeepBelow()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[BelowButton] = btn;
|
||||
}
|
||||
break;
|
||||
case 'L': // Shade button
|
||||
if ((!d->button[ShadeButton]) && isShadeable()) {
|
||||
btn = createButton(ShadeButton);
|
||||
if (!btn) break;
|
||||
bool shaded = isSetShade();
|
||||
btn->setTipText(shaded ? i18n("Unshade") : i18n("Shade"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(shaded);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotShade()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[ShadeButton] = btn;
|
||||
}
|
||||
break;
|
||||
case '_': // Spacer item
|
||||
btnContainer.append(0);
|
||||
d->button[MenuButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonApplicationMenu:
|
||||
if (!d->button[AppMenuButton]) {
|
||||
btn = createButton(AppMenuButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18nc("Button showing application menu", "Application Menu"));
|
||||
btn->setRealizeButtons(Qt::LeftButton);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(appMenuButtonPressed()), Qt::QueuedConnection);
|
||||
// Application want to show it menu
|
||||
connect(decoration(), SIGNAL(showRequest()), this, SLOT(appMenuButtonPressed()), Qt::UniqueConnection);
|
||||
// Wait for menu to become available before displaying any button
|
||||
connect(decoration(), SIGNAL(appMenuAvailable()), this, SLOT(slotAppMenuAvailable()), Qt::UniqueConnection);
|
||||
// On Kded module shutdown, hide application menu button
|
||||
connect(decoration(), SIGNAL(appMenuUnavailable()), this, SLOT(slotAppMenuUnavailable()), Qt::UniqueConnection);
|
||||
// Application menu button may need to be modified on this signal
|
||||
connect(decoration(), SIGNAL(menuHidden()), btn, SLOT(slotAppMenuHidden()), Qt::UniqueConnection);
|
||||
|
||||
|
||||
if (btn) {
|
||||
btn->setLeft(isLeft);
|
||||
btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn), layoutMetric(LM_ButtonHeight, true, btn)));
|
||||
// will be shown later on window registration
|
||||
if (btn->type() == AppMenuButton && !isPreview() && !d->wrapper->menuAvailable()) {
|
||||
btn->hide();
|
||||
} else {
|
||||
btn->show();
|
||||
}
|
||||
|
||||
btnContainer.append(btn);
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
d->button[AppMenuButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonOnAllDesktops:
|
||||
if (!d->button[OnAllDesktopsButton]) {
|
||||
btn = createButton(OnAllDesktopsButton);
|
||||
if (!btn) break;
|
||||
const bool oad = isOnAllDesktops();
|
||||
btn->setTipText(oad ? i18n("Not on all desktops") : i18n("On all desktops"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(oad);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(toggleOnAllDesktops()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[OnAllDesktopsButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonQuickHelp:
|
||||
if ((!d->button[HelpButton]) && providesContextHelp()) {
|
||||
btn = createButton(HelpButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18n("Help"));
|
||||
connect(btn, SIGNAL(clicked()), SLOT(showContextHelp()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[HelpButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonMinimize:
|
||||
if ((!d->button[MinButton]) && isMinimizable()) {
|
||||
btn = createButton(MinButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18n("Minimize"));
|
||||
connect(btn, SIGNAL(clicked()), SLOT(minimize()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[MinButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonMaximizeRestore:
|
||||
if ((!d->button[MaxButton]) && isMaximizable()) {
|
||||
btn = createButton(MaxButton);
|
||||
if (!btn) break;
|
||||
btn->setRealizeButtons(Qt::LeftButton | Qt::MidButton | Qt::RightButton);
|
||||
const bool max = maximizeMode() == MaximizeFull;
|
||||
btn->setTipText(max ? i18n("Restore") : i18n("Maximize"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(max);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotMaximize()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[MaxButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonClose:
|
||||
if ((!d->button[CloseButton]) && isCloseable()) {
|
||||
btn = createButton(CloseButton);
|
||||
if (!btn) break;
|
||||
btn->setTipText(i18n("Close"));
|
||||
connect(btn, SIGNAL(clicked()), SLOT(closeWindow()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[CloseButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonKeepAbove:
|
||||
if (!d->button[AboveButton]) {
|
||||
btn = createButton(AboveButton);
|
||||
if (!btn) break;
|
||||
bool above = keepAbove();
|
||||
btn->setTipText(above ? i18n("Do not keep above others") : i18n("Keep above others"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(above);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotKeepAbove()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[AboveButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonKeepBelow:
|
||||
if (!d->button[BelowButton]) {
|
||||
btn = createButton(BelowButton);
|
||||
if (!btn) break;
|
||||
bool below = keepBelow();
|
||||
btn->setTipText(below ? i18n("Do not keep below others") : i18n("Keep below others"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(below);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotKeepBelow()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[BelowButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonShade:
|
||||
if ((!d->button[ShadeButton]) && isShadeable()) {
|
||||
btn = createButton(ShadeButton);
|
||||
if (!btn) break;
|
||||
bool shaded = isSetShade();
|
||||
btn->setTipText(shaded ? i18n("Unshade") : i18n("Shade"));
|
||||
btn->setToggleButton(true);
|
||||
btn->setOn(shaded);
|
||||
connect(btn, SIGNAL(clicked()), SLOT(slotShade()));
|
||||
|
||||
// fix double deletion, see objDestroyed()
|
||||
connect(btn, SIGNAL(destroyed(QObject*)), this, SLOT(objDestroyed(QObject*)));
|
||||
|
||||
d->button[ShadeButton] = btn;
|
||||
}
|
||||
break;
|
||||
case DecorationButtonExplicitSpacer:
|
||||
btnContainer.append(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (btn) {
|
||||
btn->setLeft(isLeft);
|
||||
btn->setSize(QSize(layoutMetric(LM_ButtonWidth, true, btn), layoutMetric(LM_ButtonHeight, true, btn)));
|
||||
// will be shown later on window registration
|
||||
if (btn->type() == AppMenuButton && !isPreview() && !d->wrapper->menuAvailable()) {
|
||||
btn->hide();
|
||||
} else {
|
||||
btn->show();
|
||||
}
|
||||
|
||||
btnContainer.append(btn);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -410,7 +410,7 @@ private:
|
|||
|
||||
typedef QVector <KCommonDecorationButton*> ButtonContainer; ///< If the entry is 0, it's a spacer.
|
||||
int buttonContainerWidth(const ButtonContainer &btnContainer, bool countHidden = false) const;
|
||||
void addButtons(ButtonContainer &btnContainer, const QString& buttons, bool isLeft);
|
||||
void addButtons(ButtonContainer &btnContainer, const QList<DecorationButton>& buttons, bool isLeft);
|
||||
|
||||
// button hiding for small windows
|
||||
void calcHiddenButtons();
|
||||
|
|
|
@ -28,6 +28,7 @@ DEALINGS IN THE SOFTWARE.
|
|||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
#include <QWindow>
|
||||
#include <KDE/KConfigGroup>
|
||||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <fixx11h.h>
|
||||
|
@ -685,24 +686,28 @@ bool KDecorationOptions::customButtonPositions() const
|
|||
return d->custom_button_positions;
|
||||
}
|
||||
|
||||
QString KDecorationOptions::titleButtonsLeft() const
|
||||
QList<KDecorationDefines::DecorationButton> KDecorationOptions::titleButtonsLeft() const
|
||||
{
|
||||
return d->title_buttons_left;
|
||||
}
|
||||
|
||||
QString KDecorationOptions::defaultTitleButtonsLeft()
|
||||
QList<KDecorationDefines::DecorationButton> KDecorationOptions::defaultTitleButtonsLeft()
|
||||
{
|
||||
return QStringLiteral("MS");
|
||||
return QList<DecorationButton>() << DecorationButtonMenu
|
||||
<< DecorationButtonOnAllDesktops;
|
||||
}
|
||||
|
||||
QString KDecorationOptions::titleButtonsRight() const
|
||||
QList<KDecorationDefines::DecorationButton> KDecorationOptions::titleButtonsRight() const
|
||||
{
|
||||
return d->title_buttons_right;
|
||||
}
|
||||
|
||||
QString KDecorationOptions::defaultTitleButtonsRight()
|
||||
QList<KDecorationDefines::DecorationButton> KDecorationOptions::defaultTitleButtonsRight()
|
||||
{
|
||||
return QStringLiteral("HIAX");
|
||||
return QList<DecorationButton>() << DecorationButtonQuickHelp
|
||||
<< DecorationButtonMinimize
|
||||
<< DecorationButtonMaximizeRestore
|
||||
<< DecorationButtonClose;
|
||||
}
|
||||
|
||||
bool KDecorationOptions::showTooltips() const
|
||||
|
@ -752,16 +757,82 @@ void KDecorationOptions::setCustomButtonPositions(bool b)
|
|||
d->custom_button_positions = b;
|
||||
}
|
||||
|
||||
void KDecorationOptions::setTitleButtonsLeft(const QString& b)
|
||||
void KDecorationOptions::setTitleButtonsLeft(const QList<DecorationButton>& b)
|
||||
{
|
||||
d->title_buttons_left = b;
|
||||
}
|
||||
|
||||
void KDecorationOptions::setTitleButtonsRight(const QString& b)
|
||||
void KDecorationOptions::setTitleButtonsRight(const QList<DecorationButton>& b)
|
||||
{
|
||||
d->title_buttons_right = b;
|
||||
}
|
||||
|
||||
|
||||
static QHash<KDecorationDefines::DecorationButton, QByteArray> s_buttonNames;
|
||||
static void initButtons()
|
||||
{
|
||||
if (!s_buttonNames.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonMenu] = QByteArrayLiteral("M");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonApplicationMenu] = QByteArrayLiteral("N");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonOnAllDesktops] = QByteArrayLiteral("S");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonQuickHelp] = QByteArrayLiteral("H");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonMinimize] = QByteArrayLiteral("I");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonMaximizeRestore] = QByteArrayLiteral("A");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonClose] = QByteArrayLiteral("X");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonKeepAbove] = QByteArrayLiteral("F");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonKeepBelow] = QByteArrayLiteral("B");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonShade] = QByteArrayLiteral("L");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonResize] = QByteArrayLiteral("R");
|
||||
s_buttonNames[KDecorationDefines::DecorationButtonExplicitSpacer] = QByteArrayLiteral("_");
|
||||
}
|
||||
|
||||
static QString buttonsToString(const QList<KDecorationDefines::DecorationButton> &buttons)
|
||||
{
|
||||
auto buttonToString = [](KDecorationDefines::DecorationButton button) -> QByteArray {
|
||||
const auto it = s_buttonNames.constFind(button);
|
||||
if (it != s_buttonNames.constEnd()) {
|
||||
return it.value();
|
||||
}
|
||||
return QByteArray();
|
||||
};
|
||||
QByteArray ret;
|
||||
for (auto button : buttons) {
|
||||
ret.append(buttonToString(button));
|
||||
}
|
||||
return QString::fromUtf8(ret);
|
||||
}
|
||||
|
||||
QList< KDecorationDefines::DecorationButton > KDecorationOptions::readDecorationButtons(const KConfigGroup &config,
|
||||
const char *key,
|
||||
const QList< DecorationButton > &defaultValue)
|
||||
{
|
||||
initButtons();
|
||||
auto buttonFromString = [](const QByteArray &button) -> DecorationButton {
|
||||
return s_buttonNames.key(button, DecorationButtonNone);
|
||||
};
|
||||
auto buttonsFromString = [buttonFromString](const QString &buttons) -> QList<DecorationButton> {
|
||||
QList<DecorationButton> ret;
|
||||
for (auto it = buttons.constBegin(); it != buttons.constEnd(); ++it) {
|
||||
char character = (*it).toLatin1();
|
||||
const DecorationButton button = buttonFromString(QByteArray::fromRawData(&character, 1));
|
||||
if (button != DecorationButtonNone) {
|
||||
ret << button;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
return buttonsFromString(config.readEntry(key, buttonsToString(defaultValue)));
|
||||
}
|
||||
|
||||
void KDecorationOptions::writeDecorationButtons(KConfigGroup &config, const char *key,
|
||||
const QList< DecorationButton > &value)
|
||||
{
|
||||
initButtons();
|
||||
config.writeEntry(key, buttonsToString(value));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int decoration_bridge_version()
|
||||
|
|
|
@ -53,6 +53,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
class KConfig;
|
||||
class KConfigGroup;
|
||||
|
||||
/** @defgroup kdecoration KWin decorations library */
|
||||
|
||||
|
@ -235,6 +236,35 @@ public:
|
|||
ExtendedBorderRegion
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum values to identify the decorations buttons which should be used
|
||||
* by the decoration.
|
||||
*
|
||||
*/
|
||||
enum DecorationButton {
|
||||
/**
|
||||
* Invalid button value. A decoration should not create a button for
|
||||
* this type.
|
||||
*/
|
||||
DecorationButtonNone,
|
||||
DecorationButtonMenu,
|
||||
DecorationButtonApplicationMenu,
|
||||
DecorationButtonOnAllDesktops,
|
||||
DecorationButtonQuickHelp,
|
||||
DecorationButtonMinimize,
|
||||
DecorationButtonMaximizeRestore,
|
||||
DecorationButtonClose,
|
||||
DecorationButtonKeepAbove,
|
||||
DecorationButtonKeepBelow,
|
||||
DecorationButtonShade,
|
||||
DecorationButtonResize,
|
||||
/**
|
||||
* The decoration should create an empty spacer instead of a button for
|
||||
* this type.
|
||||
*/
|
||||
DecorationButtonExplicitSpacer
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the mimeType used to drag and drop clientGroupItems
|
||||
*/
|
||||
|
@ -296,46 +326,23 @@ public:
|
|||
/**
|
||||
* If customButtonPositions() returns true, titleButtonsLeft
|
||||
* returns which buttons should be on the left side of the titlebar from left
|
||||
* to right. Characters in the returned string have this meaning :
|
||||
* @li 'N' application menu button
|
||||
* @li 'M' window menu button
|
||||
* @li 'S' on_all_desktops button
|
||||
* @li 'H' quickhelp button
|
||||
* @li 'I' minimize ( iconify ) button
|
||||
* @li 'A' maximize button
|
||||
* @li 'X' close button
|
||||
* @li 'F' keep_above_others button
|
||||
* @li 'B' keep_below_others button
|
||||
* @li 'L' shade button
|
||||
* @li 'R' resize button
|
||||
* @li '_' spacer
|
||||
*
|
||||
* The default ( which is also returned if customButtonPositions returns false )
|
||||
* is "MS".
|
||||
* Unknown buttons in the returned string must be ignored.
|
||||
* The changed flags for this setting is SettingButtons.
|
||||
* to right.
|
||||
*/
|
||||
QString titleButtonsLeft() const;
|
||||
QList<DecorationButton> titleButtonsLeft() const;
|
||||
/**
|
||||
* Returns the default left button sequence
|
||||
*/
|
||||
static QString defaultTitleButtonsLeft();
|
||||
static QList<DecorationButton> defaultTitleButtonsLeft();
|
||||
/**
|
||||
* If customButtonPositions() returns true, titleButtonsRight
|
||||
* returns which buttons should be on the right side of the titlebar from left
|
||||
* to right. Characters in the return string have the same meaning like
|
||||
* in titleButtonsLeft().
|
||||
*
|
||||
* The default ( which is also returned if customButtonPositions returns false )
|
||||
* is "HIA__X".
|
||||
* Unknown buttons in the returned string must be ignored.
|
||||
* The changed flags for this setting is SettingButtons.
|
||||
* to right.
|
||||
*/
|
||||
QString titleButtonsRight() const;
|
||||
QList<DecorationButton> titleButtonsRight() const;
|
||||
/**
|
||||
* Returns the default right button sequence.
|
||||
*/
|
||||
static QString defaultTitleButtonsRight();
|
||||
static QList<DecorationButton> defaultTitleButtonsRight();
|
||||
/**
|
||||
* @returns true if the style should use tooltips for window buttons
|
||||
* The changed flags for this setting is SettingTooltips.
|
||||
|
@ -361,6 +368,30 @@ public:
|
|||
|
||||
static KDecorationOptions *self();
|
||||
|
||||
/**
|
||||
* Reads the decoration buttons from the @p config group for the @p key and takes care of
|
||||
* deserialization of the storage format.
|
||||
*
|
||||
* @param config The ConfigGroup from which the value should be read
|
||||
* @param key The name of the configuration key for the value
|
||||
* @param defaultValue The default value to use
|
||||
* @return QList< DecorationButton >
|
||||
* @see writeDecorationButtons
|
||||
*/
|
||||
static QList<DecorationButton> readDecorationButtons(const KConfigGroup &config, const char *key,
|
||||
const QList<DecorationButton> &defaultValue);
|
||||
/**
|
||||
* @brief Writes the given buttons as @p value to the configuration @p key in the given @p config.
|
||||
* Takes care of serializing to the storage format.
|
||||
*
|
||||
* @param config The ConfigGroup in which the value should be stored
|
||||
* @param key The name of the config option
|
||||
* @param value The decoration buttons to store
|
||||
* @see readDecorationButtons
|
||||
*/
|
||||
static void writeDecorationButtons(KConfigGroup &config, const char *key,
|
||||
const QList<DecorationButton> &value);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* @brief Emitted when at least one of the color settings changed.
|
||||
|
@ -465,9 +496,9 @@ protected:
|
|||
/** @internal */
|
||||
void setCustomButtonPositions(bool b);
|
||||
/** @internal */
|
||||
void setTitleButtonsLeft(const QString& b);
|
||||
void setTitleButtonsLeft(const QList<DecorationButton>& b);
|
||||
/** @internal */
|
||||
void setTitleButtonsRight(const QString& b);
|
||||
void setTitleButtonsRight(const QList<DecorationButton>& b);
|
||||
/**
|
||||
* Call to update settings when the config changes.
|
||||
* @since 4.0.1
|
||||
|
|
|
@ -169,13 +169,15 @@ void KDecorationOptionsPrivate::updateSettings(KConfig* config)
|
|||
|
||||
KConfigGroup styleConfig(config, "Style");
|
||||
// SettingsButtons
|
||||
QString old_title_buttons_left = title_buttons_left;
|
||||
QString old_title_buttons_right = title_buttons_right;
|
||||
const auto old_title_buttons_left = title_buttons_left;
|
||||
const auto old_title_buttons_right = title_buttons_right;
|
||||
bool old_custom_button_positions = custom_button_positions;
|
||||
custom_button_positions = styleConfig.readEntry("CustomButtonPositions", false);
|
||||
if (custom_button_positions) {
|
||||
title_buttons_left = styleConfig.readEntry("ButtonsOnLeft", KDecorationOptions::defaultTitleButtonsLeft());
|
||||
title_buttons_right = styleConfig.readEntry("ButtonsOnRight", KDecorationOptions::defaultTitleButtonsRight());
|
||||
title_buttons_left = q->readDecorationButtons(styleConfig, "ButtonsOnLeft",
|
||||
KDecorationOptions::defaultTitleButtonsLeft());
|
||||
title_buttons_right = q->readDecorationButtons(styleConfig, "ButtonsOnRight",
|
||||
KDecorationOptions::defaultTitleButtonsRight());
|
||||
} else {
|
||||
title_buttons_left = KDecorationOptions::defaultTitleButtonsLeft();
|
||||
title_buttons_right = KDecorationOptions::defaultTitleButtonsRight();
|
||||
|
|
|
@ -46,8 +46,8 @@ public:
|
|||
QColor colors[NUM_COLORS*2];
|
||||
QPalette *pal[NUM_COLORS*2];
|
||||
QFont activeFont, inactiveFont, activeFontSmall, inactiveFontSmall;
|
||||
QString title_buttons_left;
|
||||
QString title_buttons_right;
|
||||
QList<DecorationButton> title_buttons_left;
|
||||
QList<DecorationButton> title_buttons_right;
|
||||
bool custom_button_positions;
|
||||
bool show_tooltips;
|
||||
BorderSize border_size, cached_border_size;
|
||||
|
|
|
@ -67,7 +67,7 @@ Qt::Corner KDecorationFactory::closeButtonCorner()
|
|||
{
|
||||
if (d->closeButtonCorner)
|
||||
return d->closeButtonCorner;
|
||||
return options()->titleButtonsLeft().contains(QStringLiteral("X")) ? Qt::TopLeftCorner : Qt::TopRightCorner;
|
||||
return options()->titleButtonsLeft().contains(DecorationButtonClose) ? Qt::TopLeftCorner : Qt::TopRightCorner;
|
||||
}
|
||||
|
||||
void KDecorationFactory::setCloseButtonCorner(Qt::Corner cnr)
|
||||
|
|
Loading…
Reference in a new issue