merge r635823 from trunk
svn path=/branches/work/kwin_composite/; revision=636609
This commit is contained in:
parent
154a59c995
commit
8af21ee5b3
10 changed files with 339 additions and 350 deletions
|
@ -32,6 +32,7 @@
|
|||
#include <kglobal.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "configdialog.h"
|
||||
|
||||
PlastikConfig::PlastikConfig(KConfig* config, QWidget* parent)
|
||||
: QObject(parent), m_config(0), m_dialog(0)
|
||||
|
@ -62,8 +63,8 @@ PlastikConfig::PlastikConfig(KConfig* config, QWidget* parent)
|
|||
|
||||
PlastikConfig::~PlastikConfig()
|
||||
{
|
||||
delete m_dialog;
|
||||
delete m_config;
|
||||
if (m_dialog) delete m_dialog;
|
||||
if (m_config) delete m_config;
|
||||
}
|
||||
|
||||
void PlastikConfig::load(KConfig*)
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "mouse.h"
|
||||
#include "mouse.moc"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
char const * const cnf_Max[] = {
|
||||
|
@ -111,13 +112,13 @@ void createMaxButtonPixmaps()
|
|||
"..............."},
|
||||
};
|
||||
|
||||
QByteArray baseColor(". c " + KGlobalSettings::baseColor().name().toAscii());
|
||||
QByteArray textColor("# c " + KGlobalSettings::textColor().name().toAscii());
|
||||
QString baseColor(". c " + KGlobalSettings::baseColor().name());
|
||||
QString textColor("# c " + KGlobalSettings::textColor().name());
|
||||
for (int t = 0; t < 3; ++t)
|
||||
{
|
||||
maxButtonXpms[t][0] = "15 13 2 1";
|
||||
maxButtonXpms[t][1] = baseColor.constData();
|
||||
maxButtonXpms[t][2] = textColor.constData();
|
||||
maxButtonXpms[t][1] = baseColor.toAscii();
|
||||
maxButtonXpms[t][2] = textColor.toAscii();
|
||||
maxButtonPixmaps[t] = QPixmap(maxButtonXpms[t]);
|
||||
maxButtonPixmaps[t].setMask(maxButtonPixmaps[t].createHeuristicMask());
|
||||
}
|
||||
|
@ -373,7 +374,7 @@ KTitleBarActionsConfig::KTitleBarActionsConfig (bool _standAlone, KConfig *_conf
|
|||
coMax[b]->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ));
|
||||
}
|
||||
|
||||
connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), SLOT(paletteChanged()));
|
||||
connect(kapp, SIGNAL(kdisplayPaletteChanged()), SLOT(paletteChanged()));
|
||||
|
||||
layout->addStretch();
|
||||
|
||||
|
@ -570,11 +571,8 @@ void KTitleBarActionsConfig::save()
|
|||
if (standAlone)
|
||||
{
|
||||
config->sync();
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
|
||||
QDBusInterface kwin( "org.kde.kwin", "/KWin", "org.kde.KWin" );
|
||||
kwin.call( "reconfigure" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -849,10 +847,8 @@ void KWindowActionsConfig::save()
|
|||
if (standAlone)
|
||||
{
|
||||
config->sync();
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
QDBusInterface kwin( "org.kde.kwin", "/KWin", "org.kde.KWin" );
|
||||
kwin.call( "reconfigure" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <kmessagebox.h>
|
||||
|
||||
#include <qlabel.h>
|
||||
#include <klocale.h>
|
||||
#include <kcolorbutton.h>
|
||||
#include <kconfig.h>
|
||||
|
@ -57,6 +56,7 @@
|
|||
|
||||
#include "windows.h"
|
||||
|
||||
|
||||
// kwin config keywords
|
||||
#define KWIN_FOCUS "FocusPolicy"
|
||||
#define KWIN_PLACEMENT "Placement"
|
||||
|
@ -492,10 +492,8 @@ void KFocusConfig::save( void )
|
|||
if (standAlone)
|
||||
{
|
||||
config->sync();
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
QDBusInterface kwin( "org.kde.kwin", "/KWin", "org.kde.KWin" );
|
||||
kwin.call( "reconfigure" );
|
||||
}
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
@ -686,7 +684,7 @@ void KAdvancedConfig::load( void )
|
|||
setShadeHover(cg.readEntry(KWIN_SHADEHOVER, false));
|
||||
setShadeHoverInterval(cg.readEntry(KWIN_SHADEHOVER_INTERVAL, 250));
|
||||
|
||||
setElectricBorders(cg.readEntry(KWM_ELECTRIC_BORDER, 0));
|
||||
setElectricBorders(cg.readEntry(KWM_ELECTRIC_BORDER, false));
|
||||
setElectricBorderDelay(cg.readEntry(KWM_ELECTRIC_BORDER_DELAY, 150));
|
||||
|
||||
// setFocusStealing( cg.readEntry(KWIN_FOCUS_STEALING, 2 ));
|
||||
|
@ -721,11 +719,8 @@ void KAdvancedConfig::save( void )
|
|||
if (standAlone)
|
||||
{
|
||||
config->sync();
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
|
||||
QDBusInterface kwin( "org.kde.kwin", "/KWin", "org.kde.KWin" );
|
||||
kwin.call( "reconfigure" );
|
||||
}
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
@ -1188,10 +1183,8 @@ void KMovingConfig::save( void )
|
|||
if (standAlone)
|
||||
{
|
||||
config->sync();
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
QDBusInterface kwin( "org.kde.kwin", "/KWin", "org.kde.KWin" );
|
||||
kwin.call( "reconfigure" );
|
||||
}
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
@ -1257,8 +1250,6 @@ KTranslucencyConfig::KTranslucencyConfig (bool _standAlone, KConfig *_config, co
|
|||
"And if your GPU provides hardware-accelerated Xrender support (mainly nVidia cards):<br><br>"
|
||||
"<i>Option \"RenderAccel\" \"true\"</i><br>"
|
||||
"In <i>Section \"Device\"</i></qt>"), this);
|
||||
label->setOpenExternalLinks(true);
|
||||
label->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
|
||||
lay->addWidget(label);
|
||||
}
|
||||
else
|
||||
|
@ -1479,9 +1470,9 @@ void KTranslucencyConfig::load( void )
|
|||
|
||||
if (!kompmgrAvailable_)
|
||||
return;
|
||||
useTranslucency->setChecked(config->group("Notification Messages").readEntry("UseTranslucency", false));
|
||||
|
||||
KConfigGroup translucencyConfig(config, "Translucency");
|
||||
useTranslucency->setChecked(translucencyConfig.readEntry("UseTranslucency", false));
|
||||
activeWindowTransparency->setChecked(translucencyConfig.readEntry("TranslucentActiveWindows", false));
|
||||
inactiveWindowTransparency->setChecked(translucencyConfig.readEntry("TranslucentInactiveWindows", true));
|
||||
movingWindowTransparency->setChecked(translucencyConfig.readEntry("TranslucentMovingWindows", false));
|
||||
|
@ -1543,9 +1534,8 @@ void KTranslucencyConfig::save( void )
|
|||
{
|
||||
if (!kompmgrAvailable_)
|
||||
return;
|
||||
config->group("Notification Messages").writeEntry("UseTranslucency",useTranslucency->isChecked());
|
||||
|
||||
KConfigGroup translucencyConfig(config, "Translucency");
|
||||
translucencyConfig.writeEntry("UseTranslucency",useTranslucency->isChecked());
|
||||
translucencyConfig.writeEntry("TranslucentActiveWindows",activeWindowTransparency->isChecked());
|
||||
translucencyConfig.writeEntry("TranslucentInactiveWindows",inactiveWindowTransparency->isChecked());
|
||||
translucencyConfig.writeEntry("TranslucentMovingWindows",movingWindowTransparency->isChecked());
|
||||
|
@ -1595,11 +1585,8 @@ void KTranslucencyConfig::save( void )
|
|||
if (standAlone)
|
||||
{
|
||||
config->sync();
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
|
||||
QDBusInterface kwin( "org.kde.kwin", "/KWin", "org.kde.KWin" );
|
||||
kwin.call( "reconfigure" );
|
||||
}
|
||||
emit KCModule::changed(false);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <klocale.h>
|
||||
#include <kwin.h>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <fixx11h.h>
|
||||
|
||||
|
@ -255,10 +256,8 @@ static int edit( Window wid, bool whole_app )
|
|||
delete orig_rule;
|
||||
}
|
||||
saveRules( rules );
|
||||
// Send signal to all kwin instances
|
||||
QDBusMessage message =
|
||||
QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
QDBusInterface kwin( "org.kde.kwin", "/KWin", "org.kde.KWin" );
|
||||
kwin.call( "reconfigure" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "ruleslist.h"
|
||||
|
||||
#include <klistwidget.h>
|
||||
#include <kpushbutton.h>
|
||||
#include <assert.h>
|
||||
#include <kdebug.h>
|
||||
|
@ -29,14 +28,14 @@
|
|||
namespace KWinInternal
|
||||
{
|
||||
|
||||
KCMRulesList::KCMRulesList( QWidget* parent)
|
||||
: KCMRulesListBase( parent)
|
||||
KCMRulesList::KCMRulesList( QWidget* parent, const char* name )
|
||||
: KCMRulesListBase( parent, name )
|
||||
{
|
||||
// connect both current/selected, so that current==selected (stupid QListBox :( )
|
||||
connect( rules_listbox, SIGNAL(itemChanged(QListWidgetItem*)),
|
||||
SLOT(activeChanged(QListWidgetItem*)));
|
||||
connect( rules_listbox, SIGNAL( selectionChanged( QListWidgetItem* )),
|
||||
SLOT( activeChanged( QListWidgetItem*)));
|
||||
connect( rules_listbox, SIGNAL( currentChanged( Q3ListBoxItem* )),
|
||||
SLOT( activeChanged( Q3ListBoxItem*)));
|
||||
connect( rules_listbox, SIGNAL( selectionChanged( Q3ListBoxItem* )),
|
||||
SLOT( activeChanged( Q3ListBoxItem*)));
|
||||
connect( new_button, SIGNAL( clicked()),
|
||||
SLOT( newClicked()));
|
||||
connect( modify_button, SIGNAL( clicked()),
|
||||
|
@ -47,7 +46,7 @@ KCMRulesList::KCMRulesList( QWidget* parent)
|
|||
SLOT( moveupClicked()));
|
||||
connect( movedown_button, SIGNAL( clicked()),
|
||||
SLOT( movedownClicked()));
|
||||
connect( rules_listbox, SIGNAL(itemDoubleClicked(QListWidgetItem*) ),
|
||||
connect( rules_listbox, SIGNAL( doubleClicked ( Q3ListBoxItem * ) ),
|
||||
SLOT( modifyClicked()));
|
||||
load();
|
||||
}
|
||||
|
@ -61,16 +60,14 @@ KCMRulesList::~KCMRulesList()
|
|||
rules.clear();
|
||||
}
|
||||
|
||||
void KCMRulesList::activeChanged( QListWidgetItem* item )
|
||||
void KCMRulesList::activeChanged( Q3ListBoxItem* item )
|
||||
{
|
||||
int itemRow = rules_listbox->row(item);
|
||||
|
||||
if( item != NULL )
|
||||
item->setSelected( true ); // make current==selected
|
||||
rules_listbox->setSelected( item, true ); // make current==selected
|
||||
modify_button->setEnabled( item != NULL );
|
||||
delete_button->setEnabled( item != NULL );
|
||||
moveup_button->setEnabled( item != NULL && itemRow > 0 );
|
||||
movedown_button->setEnabled( item != NULL && itemRow < (rules_listbox->count()-1) );
|
||||
moveup_button->setEnabled( item != NULL && item->prev() != NULL );
|
||||
movedown_button->setEnabled( item != NULL && item->next() != NULL );
|
||||
}
|
||||
|
||||
void KCMRulesList::newClicked()
|
||||
|
@ -79,16 +76,16 @@ void KCMRulesList::newClicked()
|
|||
Rules* rule = dlg.edit( NULL, 0, false );
|
||||
if( rule == NULL )
|
||||
return;
|
||||
int pos = rules_listbox->currentRow() + 1;
|
||||
rules_listbox->insertItem( pos , rule->description );
|
||||
rules_listbox->item(pos)->setSelected( true );
|
||||
int pos = rules_listbox->currentItem() + 1;
|
||||
rules_listbox->insertItem( rule->description, pos );
|
||||
rules_listbox->setSelected( pos, true );
|
||||
rules.insert( rules.begin() + pos, rule );
|
||||
emit changed( true );
|
||||
}
|
||||
|
||||
void KCMRulesList::modifyClicked()
|
||||
{
|
||||
int pos = rules_listbox->currentRow();
|
||||
int pos = rules_listbox->currentItem();
|
||||
if ( pos == -1 )
|
||||
return;
|
||||
RulesDialog dlg;
|
||||
|
@ -97,29 +94,29 @@ void KCMRulesList::modifyClicked()
|
|||
return;
|
||||
delete rules[ pos ];
|
||||
rules[ pos ] = rule;
|
||||
rules_listbox->item(pos)->setText( rule->description );
|
||||
rules_listbox->changeItem( rule->description, pos );
|
||||
emit changed( true );
|
||||
}
|
||||
|
||||
void KCMRulesList::deleteClicked()
|
||||
{
|
||||
int pos = rules_listbox->currentRow();
|
||||
int pos = rules_listbox->currentItem();
|
||||
assert( pos != -1 );
|
||||
delete rules_listbox->takeItem( pos );
|
||||
rules_listbox->removeItem( pos );
|
||||
rules.erase( rules.begin() + pos );
|
||||
emit changed( true );
|
||||
}
|
||||
|
||||
void KCMRulesList::moveupClicked()
|
||||
{
|
||||
int pos = rules_listbox->currentRow();
|
||||
int pos = rules_listbox->currentItem();
|
||||
assert( pos != -1 );
|
||||
if( pos > 0 )
|
||||
{
|
||||
QString txt = rules_listbox->item(pos)->text();
|
||||
delete rules_listbox->takeItem( pos );
|
||||
rules_listbox->insertItem( pos - 1 , txt );
|
||||
rules_listbox->item(pos-1)->setSelected( true );
|
||||
QString txt = rules_listbox->text( pos );
|
||||
rules_listbox->removeItem( pos );
|
||||
rules_listbox->insertItem( txt, pos - 1 );
|
||||
rules_listbox->setSelected( pos - 1, true );
|
||||
Rules* rule = rules[ pos ];
|
||||
rules[ pos ] = rules[ pos - 1 ];
|
||||
rules[ pos - 1 ] = rule;
|
||||
|
@ -129,14 +126,14 @@ void KCMRulesList::moveupClicked()
|
|||
|
||||
void KCMRulesList::movedownClicked()
|
||||
{
|
||||
int pos = rules_listbox->currentRow();
|
||||
int pos = rules_listbox->currentItem();
|
||||
assert( pos != -1 );
|
||||
if( pos < int( rules_listbox->count()) - 1 )
|
||||
{
|
||||
QString txt = rules_listbox->item(pos)->text();
|
||||
delete rules_listbox->takeItem( pos );
|
||||
rules_listbox->insertItem( pos + 1 , txt);
|
||||
rules_listbox->item(pos+1)->setSelected( true );
|
||||
QString txt = rules_listbox->text( pos );
|
||||
rules_listbox->removeItem( pos );
|
||||
rules_listbox->insertItem( txt, pos + 1 );
|
||||
rules_listbox->setSelected( pos + 1, true );
|
||||
Rules* rule = rules[ pos ];
|
||||
rules[ pos ] = rules[ pos + 1 ];
|
||||
rules[ pos + 1 ] = rule;
|
||||
|
@ -163,10 +160,10 @@ void KCMRulesList::load()
|
|||
cfg.changeGroup( QString::number( i ));
|
||||
Rules* rule = new Rules( cfg );
|
||||
rules.append( rule );
|
||||
rules_listbox->addItem( rule->description );
|
||||
rules_listbox->insertItem( rule->description );
|
||||
}
|
||||
if( rules.count() > 0 )
|
||||
rules_listbox->item(0)->setSelected( true );
|
||||
rules_listbox->setSelected( 0, true );
|
||||
else
|
||||
activeChanged( NULL );
|
||||
}
|
||||
|
|
|
@ -144,15 +144,15 @@ unsigned long KDecorationOptionsPrivate::updateKWinSettings( KConfig* config )
|
|||
QFont old_activeFontSmall = activeFontSmall;
|
||||
QFont old_inactiveFontSmall = inactiveFontSmall;
|
||||
|
||||
QFont activeFontGuess = KGlobalSettings::windowTitleFont();
|
||||
QFont activeFontGuess = KGlobalSettings::generalFont();
|
||||
activeFontGuess.setBold(true);
|
||||
activeFontGuess.setPixelSize(12);
|
||||
|
||||
activeFont = wmConfig.readEntry("activeFont", activeFontGuess);
|
||||
inactiveFont = wmConfig.readEntry("inactiveFont", activeFont);
|
||||
|
||||
activeFontSmall = activeFont;
|
||||
#ifdef __GNUC__
|
||||
#warning KDE4 : is it useful ? ( temporary hack )
|
||||
#endif
|
||||
// activeFontSmall.setPointSize(activeFont.pointSize() - 2 > 0 ? activeFont.pointSize() - 2 : activeFont.pointSize()+1 );
|
||||
activeFontSmall = wmConfig.readEntry("activeFontSmall", activeFontSmall);
|
||||
inactiveFontSmall = wmConfig.readEntry("inactiveFontSmall", activeFontSmall);
|
||||
|
|
159
options.cpp
159
options.cpp
|
@ -47,18 +47,18 @@ Options::~Options()
|
|||
|
||||
unsigned long Options::updateSettings()
|
||||
{
|
||||
KSharedConfig::Ptr _config = KGlobal::config();
|
||||
KSharedConfig::Ptr config = KGlobal::config();
|
||||
unsigned long changed = 0;
|
||||
changed |= d->updateKWinSettings( _config.data() ); // read decoration settings
|
||||
changed |= d->updateKWinSettings( config.data() ); // read decoration settings
|
||||
|
||||
KConfigGroup config(_config, "Windows");
|
||||
moveMode = stringToMoveResizeMode( config.readEntry("MoveMode", "Opaque" ));
|
||||
resizeMode = stringToMoveResizeMode( config.readEntry("ResizeMode", "Opaque" ));
|
||||
show_geometry_tip = config.readEntry("GeometryTip", false);
|
||||
KConfigGroup windowsConfig(config, "Windows");
|
||||
moveMode = stringToMoveResizeMode( windowsConfig.readEntry("MoveMode", "Opaque" ));
|
||||
resizeMode = stringToMoveResizeMode( windowsConfig.readEntry("ResizeMode", "Opaque" ));
|
||||
show_geometry_tip = windowsConfig.readEntry("GeometryTip", false);
|
||||
|
||||
QString val;
|
||||
|
||||
val = config.readEntry ("FocusPolicy", "ClickToFocus");
|
||||
val = windowsConfig.readEntry ("FocusPolicy", "ClickToFocus");
|
||||
focusPolicy = ClickToFocus; // what a default :-)
|
||||
if ( val == "FocusFollowsMouse" )
|
||||
focusPolicy = FocusFollowsMouse;
|
||||
|
@ -67,16 +67,16 @@ unsigned long Options::updateSettings()
|
|||
else if ( val == "FocusStrictlyUnderMouse" )
|
||||
focusPolicy = FocusStrictlyUnderMouse;
|
||||
|
||||
val = config.readEntry ("AltTabStyle", "KDE");
|
||||
val = windowsConfig.readEntry ("AltTabStyle", "KDE");
|
||||
altTabStyle = KDE; // what a default :-)
|
||||
if ( val == "CDE" )
|
||||
altTabStyle = CDE;
|
||||
|
||||
rollOverDesktops = config.readEntry("RollOverDesktops", true);
|
||||
rollOverDesktops = windowsConfig.readEntry("RollOverDesktops", true);
|
||||
|
||||
// focusStealingPreventionLevel = config.readEntry( "FocusStealingPreventionLevel", 2 );
|
||||
// focusStealingPreventionLevel = config->readEntry( "FocusStealingPreventionLevel", 2 );
|
||||
// TODO use low level for now
|
||||
focusStealingPreventionLevel = config.readEntry( "FocusStealingPreventionLevel", 1 );
|
||||
focusStealingPreventionLevel = windowsConfig.readEntry( "FocusStealingPreventionLevel", 1 );
|
||||
focusStealingPreventionLevel = qMax( 0, qMin( 4, focusStealingPreventionLevel ));
|
||||
if( !focusPolicyIsReasonable()) // #48786, comments #7 and later
|
||||
focusStealingPreventionLevel = 0;
|
||||
|
@ -99,12 +99,12 @@ unsigned long Options::updateSettings()
|
|||
}
|
||||
delete gc;
|
||||
|
||||
placement = Placement::policyFromString( config.readEntry("Placement"), true );
|
||||
placement = Placement::policyFromString( windowsConfig.readEntry("Placement"), true );
|
||||
|
||||
animateShade = config.readEntry("AnimateShade", true);
|
||||
animateShade = windowsConfig.readEntry("AnimateShade", true);
|
||||
|
||||
animateMinimize = config.readEntry("AnimateMinimize", true);
|
||||
animateMinimizeSpeed = config.readEntry("AnimateMinimizeSpeed", 5 );
|
||||
animateMinimize = windowsConfig.readEntry("AnimateMinimize", true);
|
||||
animateMinimizeSpeed = windowsConfig.readEntry("AnimateMinimizeSpeed", 5 );
|
||||
|
||||
if( focusPolicy == ClickToFocus )
|
||||
{
|
||||
|
@ -115,31 +115,31 @@ unsigned long Options::updateSettings()
|
|||
}
|
||||
else
|
||||
{
|
||||
autoRaise = config.readEntry("AutoRaise", false);
|
||||
autoRaiseInterval = config.readEntry("AutoRaiseInterval", 0 );
|
||||
delayFocus = config.readEntry("DelayFocus", false);
|
||||
delayFocusInterval = config.readEntry("DelayFocusInterval", 0 );
|
||||
autoRaise = windowsConfig.readEntry("AutoRaise", false);
|
||||
autoRaiseInterval = windowsConfig.readEntry("AutoRaiseInterval", 0 );
|
||||
delayFocus = windowsConfig.readEntry("DelayFocus", false);
|
||||
delayFocusInterval = windowsConfig.readEntry("DelayFocusInterval", 0 );
|
||||
}
|
||||
|
||||
shadeHover = config.readEntry("ShadeHover", false);
|
||||
shadeHoverInterval = config.readEntry("ShadeHoverInterval", 250 );
|
||||
shadeHover = windowsConfig.readEntry("ShadeHover", false);
|
||||
shadeHoverInterval = windowsConfig.readEntry("ShadeHoverInterval", 250 );
|
||||
|
||||
// important: autoRaise implies ClickRaise
|
||||
clickRaise = autoRaise || config.readEntry("ClickRaise", true);
|
||||
clickRaise = autoRaise || windowsConfig.readEntry("ClickRaise", true);
|
||||
|
||||
borderSnapZone = config.readEntry("BorderSnapZone", 10);
|
||||
windowSnapZone = config.readEntry("WindowSnapZone", 10);
|
||||
snapOnlyWhenOverlapping = config.readEntry("SnapOnlyWhenOverlapping", false);
|
||||
electric_borders = config.readEntry("ElectricBorders", 0);
|
||||
electric_border_delay = config.readEntry("ElectricBorderDelay", 150);
|
||||
borderSnapZone = windowsConfig.readEntry("BorderSnapZone", 10);
|
||||
windowSnapZone = windowsConfig.readEntry("WindowSnapZone", 10);
|
||||
snapOnlyWhenOverlapping = windowsConfig.readEntry("SnapOnlyWhenOverlapping", false);
|
||||
electric_borders = windowsConfig.readEntry("ElectricBorders", 0);
|
||||
electric_border_delay = windowsConfig.readEntry("ElectricBorderDelay", 150);
|
||||
|
||||
OpTitlebarDblClick = windowOperation( config.readEntry("TitlebarDoubleClickCommand", "Shade"), true );
|
||||
d->OpMaxButtonLeftClick = windowOperation( config.readEntry("MaximizeButtonLeftClickCommand", "Maximize"), true );
|
||||
d->OpMaxButtonMiddleClick = windowOperation( config.readEntry("MaximizeButtonMiddleClickCommand", "Maximize (vertical only)"), true );
|
||||
d->OpMaxButtonRightClick = windowOperation( config.readEntry("MaximizeButtonRightClickCommand", "Maximize (horizontal only)"), true );
|
||||
OpTitlebarDblClick = windowOperation( windowsConfig.readEntry("TitlebarDoubleClickCommand", "Shade"), true );
|
||||
d->OpMaxButtonLeftClick = windowOperation( windowsConfig.readEntry("MaximizeButtonLeftClickCommand", "Maximize"), true );
|
||||
d->OpMaxButtonMiddleClick = windowOperation( windowsConfig.readEntry("MaximizeButtonMiddleClickCommand", "Maximize (vertical only)"), true );
|
||||
d->OpMaxButtonRightClick = windowOperation( windowsConfig.readEntry("MaximizeButtonRightClickCommand", "Maximize (horizontal only)"), true );
|
||||
|
||||
ignorePositionClasses = config.readEntry("IgnorePositionClasses",QStringList());
|
||||
ignoreFocusStealingClasses = config.readEntry("IgnoreFocusStealingClasses",QStringList());
|
||||
ignorePositionClasses = windowsConfig.readEntry("IgnorePositionClasses",QStringList());
|
||||
ignoreFocusStealingClasses = windowsConfig.readEntry("IgnoreFocusStealingClasses",QStringList());
|
||||
// Qt3.2 and older had resource class all lowercase, but Qt3.3 has it capitalized
|
||||
// therefore Client::resourceClass() forces lowercase, force here lowercase as well
|
||||
for( QStringList::Iterator it = ignorePositionClasses.begin();
|
||||
|
@ -151,49 +151,70 @@ unsigned long Options::updateSettings()
|
|||
++it )
|
||||
(*it) = (*it).toLower();
|
||||
|
||||
killPingTimeout = config.readEntry( "KillPingTimeout", 5000 );
|
||||
hideUtilityWindowsForInactive = config.readEntry( "HideUtilityWindowsForInactive", true);
|
||||
showDesktopIsMinimizeAll = config.readEntry( "ShowDesktopIsMinimizeAll", false );
|
||||
killPingTimeout = windowsConfig.readEntry( "KillPingTimeout", 5000 );
|
||||
hideUtilityWindowsForInactive = windowsConfig.readEntry( "HideUtilityWindowsForInactive", true);
|
||||
showDesktopIsMinimizeAll = windowsConfig.readEntry( "ShowDesktopIsMinimizeAll", false );
|
||||
|
||||
// Mouse bindings
|
||||
config.changeGroup("MouseBindings");
|
||||
CmdActiveTitlebar1 = mouseCommand(config.readEntry("CommandActiveTitlebar1","Raise"), true );
|
||||
CmdActiveTitlebar2 = mouseCommand(config.readEntry("CommandActiveTitlebar2","Lower"), true );
|
||||
CmdActiveTitlebar3 = mouseCommand(config.readEntry("CommandActiveTitlebar3","Operations menu"), true );
|
||||
CmdInactiveTitlebar1 = mouseCommand(config.readEntry("CommandInactiveTitlebar1","Activate and raise"), true );
|
||||
CmdInactiveTitlebar2 = mouseCommand(config.readEntry("CommandInactiveTitlebar2","Activate and lower"), true );
|
||||
CmdInactiveTitlebar3 = mouseCommand(config.readEntry("CommandInactiveTitlebar3","Operations menu"), true );
|
||||
CmdTitlebarWheel = mouseWheelCommand(config.readEntry("CommandTitlebarWheel","Nothing"));
|
||||
CmdWindow1 = mouseCommand(config.readEntry("CommandWindow1","Activate, raise and pass click"), false );
|
||||
CmdWindow2 = mouseCommand(config.readEntry("CommandWindow2","Activate and pass click"), false );
|
||||
CmdWindow3 = mouseCommand(config.readEntry("CommandWindow3","Activate and pass click"), false );
|
||||
CmdAllModKey = (config.readEntry("CommandAllKey","Alt") == "Meta") ? Qt::Key_Meta : Qt::Key_Alt;
|
||||
CmdAll1 = mouseCommand(config.readEntry("CommandAll1","Move"), false );
|
||||
CmdAll2 = mouseCommand(config.readEntry("CommandAll2","Toggle raise and lower"), false );
|
||||
CmdAll3 = mouseCommand(config.readEntry("CommandAll3","Resize"), false );
|
||||
CmdAllWheel = mouseWheelCommand(config.readEntry("CommandAllWheel","Nothing"));
|
||||
KConfigGroup mouseConfig(config, "MouseBindings");
|
||||
CmdActiveTitlebar1 = mouseCommand(mouseConfig.readEntry("CommandActiveTitlebar1","Raise"), true );
|
||||
CmdActiveTitlebar2 = mouseCommand(mouseConfig.readEntry("CommandActiveTitlebar2","Lower"), true );
|
||||
CmdActiveTitlebar3 = mouseCommand(mouseConfig.readEntry("CommandActiveTitlebar3","Operations menu"), true );
|
||||
CmdInactiveTitlebar1 = mouseCommand(mouseConfig.readEntry("CommandInactiveTitlebar1","Activate and raise"), true );
|
||||
CmdInactiveTitlebar2 = mouseCommand(mouseConfig.readEntry("CommandInactiveTitlebar2","Activate and lower"), true );
|
||||
CmdInactiveTitlebar3 = mouseCommand(mouseConfig.readEntry("CommandInactiveTitlebar3","Operations menu"), true );
|
||||
CmdTitlebarWheel = mouseWheelCommand(mouseConfig.readEntry("CommandTitlebarWheel","Nothing"));
|
||||
CmdWindow1 = mouseCommand(mouseConfig.readEntry("CommandWindow1","Activate, raise and pass click"), false );
|
||||
CmdWindow2 = mouseCommand(mouseConfig.readEntry("CommandWindow2","Activate and pass click"), false );
|
||||
CmdWindow3 = mouseCommand(mouseConfig.readEntry("CommandWindow3","Activate and pass click"), false );
|
||||
CmdAllModKey = (mouseConfig.readEntry("CommandAllKey","Alt") == "Meta") ? Qt::Key_Meta : Qt::Key_Alt;
|
||||
CmdAll1 = mouseCommand(mouseConfig.readEntry("CommandAll1","Move"), false );
|
||||
CmdAll2 = mouseCommand(mouseConfig.readEntry("CommandAll2","Toggle raise and lower"), false );
|
||||
CmdAll3 = mouseCommand(mouseConfig.readEntry("CommandAll3","Resize"), false );
|
||||
CmdAllWheel = mouseWheelCommand(mouseConfig.readEntry("CommandAllWheel","Nothing"));
|
||||
|
||||
//translucency settings - TODO
|
||||
useTranslucency = _config->group("Notification Messages").readEntry("UseTranslucency", false);
|
||||
config.changeGroup("Translucency");
|
||||
translucentActiveWindows = config.readEntry("TranslucentActiveWindows", false);
|
||||
activeWindowOpacity = uint((config.readEntry("ActiveWindowOpacity", 100)/100.0)*0xFFFFFFFF);
|
||||
translucentInactiveWindows = config.readEntry("TranslucentInactiveWindows", false);
|
||||
inactiveWindowOpacity = uint((config.readEntry("InactiveWindowOpacity", 75)/100.0)*0xFFFFFFFF);
|
||||
translucentMovingWindows = config.readEntry("TranslucentMovingWindows", false);
|
||||
movingWindowOpacity = uint((config.readEntry("MovingWindowOpacity", 50)/100.0)*0xFFFFFFFF);
|
||||
translucentDocks = config.readEntry("TranslucentDocks", false);
|
||||
dockOpacity = uint((config.readEntry("DockOpacity", 80)/100.0)*0xFFFFFFFF);
|
||||
keepAboveAsActive = config.readEntry("TreatKeepAboveAsActive", true);
|
||||
KConfigGroup translucencyConfig(config, "Translucency");
|
||||
useTranslucency = translucencyConfig.readEntry("UseTranslucency", true);
|
||||
translucentActiveWindows = translucencyConfig.readEntry("TranslucentActiveWindows", false);
|
||||
activeWindowOpacity = uint((translucencyConfig.readEntry("ActiveWindowOpacity", 100)/100.0)*0xFFFFFFFF);
|
||||
translucentInactiveWindows = translucencyConfig.readEntry("TranslucentInactiveWindows", false);
|
||||
inactiveWindowOpacity = uint((translucencyConfig.readEntry("InactiveWindowOpacity", 75)/100.0)*0xFFFFFFFF);
|
||||
translucentMovingWindows = translucencyConfig.readEntry("TranslucentMovingWindows", false);
|
||||
movingWindowOpacity = uint((translucencyConfig.readEntry("MovingWindowOpacity", 50)/100.0)*0xFFFFFFFF);
|
||||
translucentDocks = translucencyConfig.readEntry("TranslucentDocks", false);
|
||||
dockOpacity = uint((translucencyConfig.readEntry("DockOpacity", 80)/100.0)*0xFFFFFFFF);
|
||||
keepAboveAsActive = translucencyConfig.readEntry("TreatKeepAboveAsActive", true);
|
||||
//TODO: remove this variable
|
||||
useTitleMenuSlider = true;
|
||||
activeWindowShadowSize = config.readEntry("ActiveWindowShadowSize", 200);
|
||||
inactiveWindowShadowSize = config.readEntry("InactiveWindowShadowSize", 100);
|
||||
dockShadowSize = config.readEntry("DockShadowSize", 80);
|
||||
removeShadowsOnMove = config.readEntry("RemoveShadowsOnMove", true);
|
||||
removeShadowsOnResize = config.readEntry("RemoveShadowsOnResize", true);
|
||||
onlyDecoTranslucent = config.readEntry("OnlyDecoTranslucent", false);
|
||||
activeWindowShadowSize = translucencyConfig.readEntry("ActiveWindowShadowSize", 200);
|
||||
inactiveWindowShadowSize = translucencyConfig.readEntry("InactiveWindowShadowSize", 100);
|
||||
dockShadowSize = translucencyConfig.readEntry("DockShadowSize", 80);
|
||||
removeShadowsOnMove = translucencyConfig.readEntry("RemoveShadowsOnMove", true);
|
||||
removeShadowsOnResize = translucencyConfig.readEntry("RemoveShadowsOnResize", true);
|
||||
onlyDecoTranslucent = translucencyConfig.readEntry("OnlyDecoTranslucent", false);
|
||||
|
||||
refreshRate = config->readEntry( "RefreshRate", 0 );
|
||||
smoothScale = qBound( -1, config->readEntry( "SmoothScale", -1 ), 2 );
|
||||
|
||||
QString glmode = config->readEntry("GLMode", "TFP" ).upper();
|
||||
if( glmode == "TFP" )
|
||||
glMode = GLTFP;
|
||||
else if( glmode == "SHM" )
|
||||
glMode = GLSHM;
|
||||
else
|
||||
glMode = GLFallback;
|
||||
glAlwaysRebind = config->readEntry("GLAlwaysRebind", false );
|
||||
glDirect = config->readEntry("GLDirect", true );
|
||||
glVSync = config->readEntry("GLVSync", true );
|
||||
|
||||
config->setGroup( "Effects" );
|
||||
defaultEffects = config->readEntry( "Load", QStringList() << "ShowFps" << "Fade" );
|
||||
|
||||
config->setGroup( "EffectShowFps" );
|
||||
effectShowFpsAlpha = config->readEntry( "Alpha", 0.5 );
|
||||
effectShowFpsX = config->readEntry( "X", -10000 );
|
||||
effectShowFpsY = config->readEntry( "Y", 0 );
|
||||
// Read button tooltip animation effect from kdeglobals
|
||||
// Since we want to allow users to enable window decoration tooltips
|
||||
// and not kstyle tooltips and vise-versa, we don't read the
|
||||
|
|
24
sm.cpp
24
sm.cpp
|
@ -11,7 +11,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "sm.h"
|
||||
|
||||
//#include <kdebug.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
|
@ -23,6 +22,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "client.h"
|
||||
#include <QSocketNotifier>
|
||||
#include <qsessionmanager.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
@ -256,6 +256,28 @@ bool Workspace::sessionInfoWindowTypeMatch( Client* c, SessionInfo* info )
|
|||
return info->windowType == c->windowType();
|
||||
}
|
||||
|
||||
// maybe needed later
|
||||
#if 0
|
||||
// KMainWindow's without name() given have WM_WINDOW_ROLE in the form
|
||||
// of <appname>-mainwindow#<number>
|
||||
// when comparing them for fake session info, it's probably better to check
|
||||
// them without the trailing number
|
||||
bool Workspace::windowRoleMatch( const QByteArray& role1, const QByteArray& role2 )
|
||||
{
|
||||
if( role1.isEmpty() && role2.isEmpty())
|
||||
return true;
|
||||
int pos1 = role1.find( '#' );
|
||||
int pos2 = role2.find( '#' );
|
||||
bool ret;
|
||||
if( pos1 < 0 || pos2 < 0 || pos1 != pos2 )
|
||||
ret = role1 == role2;
|
||||
else
|
||||
ret = qstrncmp( role1, role2, pos1 ) == 0;
|
||||
kDebug() << "WR:" << role1 << ":" << pos1 << ":" << role2 << ":" << pos2 << ":::" << ret << endl;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* const window_type_names[] =
|
||||
{
|
||||
"Unknown", "Normal" , "Desktop", "Dock", "Toolbar", "Menu", "Dialog",
|
||||
|
|
206
tabbox.cpp
206
tabbox.cpp
|
@ -44,7 +44,7 @@ namespace KWinInternal
|
|||
extern QPixmap* kwin_get_menu_pix_hack();
|
||||
|
||||
TabBox::TabBox( Workspace *ws, const char *name )
|
||||
: Q3Frame( 0, name, Qt::WNoAutoErase ), current_client( NULL ), wspace(ws)
|
||||
: Q3Frame( 0, name, Qt::WNoAutoErase | Qt::X11BypassWindowManagerHint ), client(0), wspace(ws)
|
||||
{
|
||||
setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
setLineWidth(2);
|
||||
|
@ -54,28 +54,14 @@ TabBox::TabBox( Workspace *ws, const char *name )
|
|||
|
||||
no_tasks = i18n("*** No Windows ***");
|
||||
m = DesktopMode; // init variables
|
||||
updateKeyMapping();
|
||||
reconfigure();
|
||||
reset();
|
||||
connect(&delayedShowTimer, SIGNAL(timeout()), this, SLOT(show()));
|
||||
|
||||
XSetWindowAttributes attr;
|
||||
attr.override_redirect = 1;
|
||||
outline_left = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
|
||||
outline_right = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
|
||||
outline_top = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
|
||||
outline_bottom = XCreateWindow( display(), rootWindow(), 0, 0, 1, 1, 0,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
|
||||
}
|
||||
|
||||
TabBox::~TabBox()
|
||||
{
|
||||
XDestroyWindow( display(), outline_left );
|
||||
XDestroyWindow( display(), outline_right );
|
||||
XDestroyWindow( display(), outline_top );
|
||||
XDestroyWindow( display(), outline_bottom );
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,10 +111,6 @@ void TabBox::createClientList(ClientList &list, int desktop /*-1 = all*/, Client
|
|||
list += c;
|
||||
else if( !list.contains( modal ))
|
||||
list += modal;
|
||||
else
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +138,7 @@ void TabBox::reset()
|
|||
{
|
||||
int w, h, cw = 0, wmax = 0;
|
||||
|
||||
QRect r = KGlobalSettings::desktopGeometry(QCursor::pos());
|
||||
QRect r = KGlobalSettings::desktopGeometry(cursorPos());
|
||||
|
||||
// calculate height of 1 line
|
||||
// fontheight + 1 pixel above + 1 pixel below, or 32x32 icon + 2 pixel above + below
|
||||
|
@ -164,10 +146,10 @@ void TabBox::reset()
|
|||
|
||||
if ( mode() == WindowsMode )
|
||||
{
|
||||
setCurrentClient( workspace()->activeClient());
|
||||
client = workspace()->activeClient();
|
||||
|
||||
// get all clients to show
|
||||
createClientList(clients, options_traverse_all ? -1 : workspace()->currentDesktop(), current_client, true);
|
||||
createClientList(clients, options_traverse_all ? -1 : workspace()->currentDesktop(), client, true);
|
||||
|
||||
// calculate maximum caption width
|
||||
cw = fontMetrics().width(no_tasks)+20;
|
||||
|
@ -244,8 +226,7 @@ void TabBox::nextPrev( bool next)
|
|||
{
|
||||
if ( mode() == WindowsMode )
|
||||
{
|
||||
Client* firstClient = NULL;
|
||||
Client* client = current_client;
|
||||
Client* firstClient = 0;
|
||||
do
|
||||
{
|
||||
if ( next )
|
||||
|
@ -265,7 +246,6 @@ void TabBox::nextPrev( bool next)
|
|||
break;
|
||||
}
|
||||
} while ( client && !clients.contains( client ));
|
||||
setCurrentClient( client );
|
||||
}
|
||||
else if( mode() == DesktopMode )
|
||||
{
|
||||
|
@ -303,18 +283,9 @@ Client* TabBox::currentClient()
|
|||
{
|
||||
if ( mode() != WindowsMode )
|
||||
return 0;
|
||||
if (!workspace()->hasClient( current_client ))
|
||||
if (!workspace()->hasClient( client ))
|
||||
return 0;
|
||||
return current_client;
|
||||
}
|
||||
|
||||
void TabBox::setCurrentClient( Client* c )
|
||||
{
|
||||
if( current_client != c )
|
||||
{
|
||||
current_client = c;
|
||||
updateOutline();
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -336,11 +307,6 @@ int TabBox::currentDesktop()
|
|||
*/
|
||||
void TabBox::showEvent( QShowEvent* )
|
||||
{
|
||||
updateOutline();
|
||||
XRaiseWindow( display(), outline_left );
|
||||
XRaiseWindow( display(), outline_right );
|
||||
XRaiseWindow( display(), outline_top );
|
||||
XRaiseWindow( display(), outline_bottom );
|
||||
raise();
|
||||
}
|
||||
|
||||
|
@ -350,10 +316,6 @@ void TabBox::showEvent( QShowEvent* )
|
|||
*/
|
||||
void TabBox::hideEvent( QHideEvent* )
|
||||
{
|
||||
XUnmapWindow( display(), outline_left );
|
||||
XUnmapWindow( display(), outline_right );
|
||||
XUnmapWindow( display(), outline_top );
|
||||
XUnmapWindow( display(), outline_bottom );
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -392,7 +354,7 @@ void TabBox::drawContents( QPainter * )
|
|||
if ( workspace()->hasClient( *it ) ) // safety
|
||||
{
|
||||
// draw highlight background
|
||||
if ( (*it) == current_client )
|
||||
if ( (*it) == currentClient() )
|
||||
p.fillRect(x, y, r.width(), lineHeight, palette().brush( QPalette::Highlight ));
|
||||
|
||||
// draw icon
|
||||
|
@ -426,10 +388,10 @@ void TabBox::drawContents( QPainter * )
|
|||
else
|
||||
s += (*it)->caption();
|
||||
|
||||
s = fontMetrics().elidedText(s, Qt::ElideMiddle, r.width() - 5 - iconWidth - 8);
|
||||
s = KStringHandler::cPixelSqueeze(s, fontMetrics(), r.width() - 5 - iconWidth - 8);
|
||||
|
||||
// draw text
|
||||
if ( (*it) == current_client )
|
||||
if ( (*it) == currentClient() )
|
||||
p.setPen(palette().color( QPalette::HighlightedText ));
|
||||
else if( (*it)->isMinimized())
|
||||
{
|
||||
|
@ -547,91 +509,6 @@ void TabBox::drawContents( QPainter * )
|
|||
localPainter.drawImage( QPoint( r.x(), r.y() ), pix.toImage() );
|
||||
}
|
||||
|
||||
void TabBox::updateOutline()
|
||||
{
|
||||
Client* c = currentClient();
|
||||
if( c == NULL || this->isHidden() || !c->isShown( true ) || !c->isOnCurrentDesktop())
|
||||
{
|
||||
XUnmapWindow( display(), outline_left );
|
||||
XUnmapWindow( display(), outline_right );
|
||||
XUnmapWindow( display(), outline_top );
|
||||
XUnmapWindow( display(), outline_bottom );
|
||||
return;
|
||||
}
|
||||
// left/right parts are between top/bottom, they don't reach as far as the corners
|
||||
XMoveResizeWindow( display(), outline_left, c->x(), c->y() + 5, 5, c->height() - 10 );
|
||||
XMoveResizeWindow( display(), outline_right, c->x() + c->width() - 5, c->y() + 5, 5, c->height() - 10 );
|
||||
XMoveResizeWindow( display(), outline_top, c->x(), c->y(), c->width(), 5 );
|
||||
XMoveResizeWindow( display(), outline_bottom, c->x(), c->y() + c->height() - 5, c->width(), 5 );
|
||||
{
|
||||
QPixmap pix( 5, c->height() - 10 );
|
||||
QPainter p( &pix );
|
||||
p.setPen( Qt::white );
|
||||
p.drawLine( 0, 0, 0, pix.height() - 1 );
|
||||
p.drawLine( 4, 0, 4, pix.height() - 1 );
|
||||
p.setPen( Qt::gray );
|
||||
p.drawLine( 1, 0, 1, pix.height() - 1 );
|
||||
p.drawLine( 3, 0, 3, pix.height() - 1 );
|
||||
p.setPen( Qt::black );
|
||||
p.drawLine( 2, 0, 2, pix.height() - 1 );
|
||||
p.end();
|
||||
XSetWindowBackgroundPixmap( display(), outline_left, pix.handle());
|
||||
XSetWindowBackgroundPixmap( display(), outline_right, pix.handle());
|
||||
}
|
||||
{
|
||||
QPixmap pix( c->width(), 5 );
|
||||
QPainter p( &pix );
|
||||
p.setPen( Qt::white );
|
||||
p.drawLine( 0, 0, pix.width() - 1 - 0, 0 );
|
||||
p.drawLine( 4, 4, pix.width() - 1 - 4, 4 );
|
||||
p.drawLine( 0, 0, 0, 4 );
|
||||
p.drawLine( pix.width() - 1 - 0, 0, pix.width() - 1 - 0, 4 );
|
||||
p.setPen( Qt::gray );
|
||||
p.drawLine( 1, 1, pix.width() - 1 - 1, 1 );
|
||||
p.drawLine( 3, 3, pix.width() - 1 - 3, 3 );
|
||||
p.drawLine( 1, 1, 1, 4 );
|
||||
p.drawLine( 3, 3, 3, 4 );
|
||||
p.drawLine( pix.width() - 1 - 1, 1, pix.width() - 1 - 1, 4 );
|
||||
p.drawLine( pix.width() - 1 - 3, 3, pix.width() - 1 - 3, 4 );
|
||||
p.setPen( Qt::black );
|
||||
p.drawLine( 2, 2, pix.width() - 1 - 2, 2 );
|
||||
p.drawLine( 2, 2, 2, 4 );
|
||||
p.drawLine( pix.width() - 1 - 2, 2, pix.width() - 1 - 2, 4 );
|
||||
p.end();
|
||||
XSetWindowBackgroundPixmap( display(), outline_top, pix.handle());
|
||||
}
|
||||
{
|
||||
QPixmap pix( c->width(), 5 );
|
||||
QPainter p( &pix );
|
||||
p.setPen( Qt::white );
|
||||
p.drawLine( 4, 0, pix.width() - 1 - 4, 0 );
|
||||
p.drawLine( 0, 4, pix.width() - 1 - 0, 4 );
|
||||
p.drawLine( 0, 4, 0, 0 );
|
||||
p.drawLine( pix.width() - 1 - 0, 4, pix.width() - 1 - 0, 0 );
|
||||
p.setPen( Qt::gray );
|
||||
p.drawLine( 3, 1, pix.width() - 1 - 3, 1 );
|
||||
p.drawLine( 1, 3, pix.width() - 1 - 1, 3 );
|
||||
p.drawLine( 3, 1, 3, 0 );
|
||||
p.drawLine( 1, 3, 1, 0 );
|
||||
p.drawLine( pix.width() - 1 - 3, 1, pix.width() - 1 - 3, 0 );
|
||||
p.drawLine( pix.width() - 1 - 1, 3, pix.width() - 1 - 1, 0 );
|
||||
p.setPen( Qt::black );
|
||||
p.drawLine( 2, 2, pix.width() - 1 - 2, 2 );
|
||||
p.drawLine( 2, 0, 2, 2 );
|
||||
p.drawLine( pix.width() - 1 - 2, 0, pix.width() - 1 - 2 , 2 );
|
||||
p.end();
|
||||
XSetWindowBackgroundPixmap( display(), outline_bottom, pix.handle());
|
||||
}
|
||||
XClearWindow( display(), outline_left );
|
||||
XClearWindow( display(), outline_right );
|
||||
XClearWindow( display(), outline_top );
|
||||
XClearWindow( display(), outline_bottom );
|
||||
XMapWindow( display(), outline_left );
|
||||
XMapWindow( display(), outline_right );
|
||||
XMapWindow( display(), outline_top );
|
||||
XMapWindow( display(), outline_bottom );
|
||||
}
|
||||
|
||||
void TabBox::hide()
|
||||
{
|
||||
delayedShowTimer.stop();
|
||||
|
@ -708,7 +585,7 @@ void TabBox::handleMouseEvent( XEvent* e )
|
|||
{
|
||||
if( workspace()->hasClient( *it ) && (num == 0) ) // safety
|
||||
{
|
||||
setCurrentClient( *it );
|
||||
client = *it;
|
||||
break;
|
||||
}
|
||||
num--;
|
||||
|
@ -788,6 +665,10 @@ bool areKeySymXsDepressed( bool bAll, const uint keySyms[], int nKeySyms )
|
|||
return bAll;
|
||||
}
|
||||
|
||||
static const int MAX_KEYSYMS = 4;
|
||||
static uint alt_keysyms[ MAX_KEYSYMS ];
|
||||
static uint win_keysyms[ MAX_KEYSYMS ];
|
||||
|
||||
static bool areModKeysDepressed( const QKeySequence& seq )
|
||||
{
|
||||
uint rgKeySyms[10];
|
||||
|
@ -808,18 +689,17 @@ static bool areModKeysDepressed( const QKeySequence& seq )
|
|||
}
|
||||
if( mod & Qt::ALT )
|
||||
{
|
||||
rgKeySyms[nKeySyms++] = XK_Alt_L;
|
||||
rgKeySyms[nKeySyms++] = XK_Alt_R;
|
||||
for( int i = 0;
|
||||
i < MAX_KEYSYMS && alt_keysyms[ i ] != NoSymbol;
|
||||
++i )
|
||||
rgKeySyms[nKeySyms++] = alt_keysyms[ i ];
|
||||
}
|
||||
if( mod & Qt::META )
|
||||
{
|
||||
// It would take some code to determine whether the Win key
|
||||
// is associated with Super or Meta, so check for both.
|
||||
// See bug #140023 for details.
|
||||
rgKeySyms[nKeySyms++] = XK_Super_L;
|
||||
rgKeySyms[nKeySyms++] = XK_Super_R;
|
||||
rgKeySyms[nKeySyms++] = XK_Meta_L;
|
||||
rgKeySyms[nKeySyms++] = XK_Meta_R;
|
||||
for( int i = 0;
|
||||
i < MAX_KEYSYMS && win_keysyms[ i ] != NoSymbol;
|
||||
++i )
|
||||
rgKeySyms[nKeySyms++] = win_keysyms[ i ];
|
||||
}
|
||||
|
||||
return areKeySymXsDepressed( false, rgKeySyms, nKeySyms );
|
||||
|
@ -833,6 +713,44 @@ static bool areModKeysDepressed( const KShortcut& cut )
|
|||
return false;
|
||||
}
|
||||
|
||||
void TabBox::updateKeyMapping()
|
||||
{
|
||||
const int size = 6;
|
||||
uint keysyms[ size ] = { XK_Alt_L, XK_Alt_R, XK_Super_L, XK_Super_R, XK_Meta_L, XK_Meta_R };
|
||||
XModifierKeymap* map = XGetModifierMapping( display() );
|
||||
int altpos = 0;
|
||||
int winpos = 0;
|
||||
int winmodpos = -1;
|
||||
int winmod = KKeyServer::modXMeta();
|
||||
while( winmod > 0 ) // get position of the set bit in winmod
|
||||
{
|
||||
winmod >>= 1;
|
||||
++winmodpos;
|
||||
}
|
||||
for( int i = 0;
|
||||
i < MAX_KEYSYMS;
|
||||
++i )
|
||||
alt_keysyms[ i ] = win_keysyms[ i ] = NoSymbol;
|
||||
for( int i = 0;
|
||||
i < size;
|
||||
++i )
|
||||
{
|
||||
KeyCode keycode = XKeysymToKeycode( display(), keysyms[ i ] );
|
||||
for( int j = 0;
|
||||
j < map->max_keypermod;
|
||||
++j )
|
||||
{
|
||||
if( map->modifiermap[ 3 * map->max_keypermod + j ] == keycode ) // Alt
|
||||
if( altpos < MAX_KEYSYMS )
|
||||
alt_keysyms[ altpos++ ] = keysyms[ i ];
|
||||
if( winmodpos >= 0 && map->modifiermap[ winmodpos * map->max_keypermod + j ] == keycode )
|
||||
if( winpos < MAX_KEYSYMS )
|
||||
win_keysyms[ winpos++ ] = keysyms[ i ];
|
||||
}
|
||||
}
|
||||
XFreeModifiermap( map );
|
||||
}
|
||||
|
||||
void Workspace::slotWalkThroughWindows()
|
||||
{
|
||||
if ( root != rootWindow() )
|
||||
|
|
158
workspace.cpp
158
workspace.cpp
|
@ -43,6 +43,10 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "group.h"
|
||||
#include "rules.h"
|
||||
#include "kwinadaptor.h"
|
||||
#include "unmanaged.h"
|
||||
#include "scene.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/keysym.h>
|
||||
|
@ -94,6 +98,7 @@ Workspace::Workspace( bool restore )
|
|||
popupinfo (0),
|
||||
popup (0),
|
||||
advanced_popup (0),
|
||||
trans_popup (0),
|
||||
desk_popup (0),
|
||||
desk_popup_index (0),
|
||||
keys (0),
|
||||
|
@ -123,12 +128,16 @@ Workspace::Workspace( bool restore )
|
|||
topmenu_space( NULL ),
|
||||
set_active_client_recursion( 0 ),
|
||||
block_stacking_updates( 0 ),
|
||||
forced_global_mouse_grab( false )
|
||||
forced_global_mouse_grab( false ),
|
||||
cm_selection( NULL ),
|
||||
compositeRate( 0 ),
|
||||
overlay( None ),
|
||||
transSlider( NULL ),
|
||||
transButton( NULL )
|
||||
{
|
||||
(void) new KWinAdaptor( this );
|
||||
QDBusConnection dbus = QDBusConnection::sessionBus();
|
||||
dbus.registerObject("/KWin", this);
|
||||
dbus.connect(QString(), "/KWin", "org.kde.KWin", "reloadConfig", this, SLOT(slotReloadConfig()));
|
||||
QDBusConnection::sessionBus().registerObject("/KWin", this);
|
||||
|
||||
_self = this;
|
||||
mgr = new PluginMgr;
|
||||
root = rootWindow();
|
||||
|
@ -169,10 +178,12 @@ Workspace::Workspace( bool restore )
|
|||
ColormapChangeMask |
|
||||
SubstructureRedirectMask |
|
||||
SubstructureNotifyMask |
|
||||
FocusChangeMask // for NotifyDetailNone
|
||||
FocusChangeMask | // for NotifyDetailNone
|
||||
ExposureMask
|
||||
);
|
||||
|
||||
Shape::init();
|
||||
Extensions::init();
|
||||
setupCompositing();
|
||||
|
||||
// compatibility
|
||||
long data = 1;
|
||||
|
@ -278,7 +289,6 @@ void Workspace::init()
|
|||
NET::WM2ExtendedStrut |
|
||||
NET::WM2KDETemporaryRules |
|
||||
NET::WM2ShowingDesktop |
|
||||
NET::WM2DesktopLayout |
|
||||
0
|
||||
,
|
||||
NET::ActionMove |
|
||||
|
@ -322,6 +332,7 @@ void Workspace::init()
|
|||
connect(&reconfigureTimer, SIGNAL(timeout()), this,
|
||||
SLOT(slotReconfigure()));
|
||||
connect( &updateToolWindowsTimer, SIGNAL( timeout()), this, SLOT( slotUpdateToolWindows()));
|
||||
connect( &compositeTimer, SIGNAL( timeout()), SLOT( performCompositing()));
|
||||
|
||||
connect(KGlobalSettings::self(), SIGNAL(appearanceChanged()), this,
|
||||
SLOT(slotReconfigure()));
|
||||
|
@ -359,7 +370,10 @@ void Workspace::init()
|
|||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(display(), wins[i], &attr);
|
||||
if (attr.override_redirect )
|
||||
{
|
||||
createUnmanaged( wins[ i ] );
|
||||
continue;
|
||||
}
|
||||
if( topmenu_space && topmenu_space->winId() == wins[ i ] )
|
||||
continue;
|
||||
if (attr.map_state != IsUnmapped)
|
||||
|
@ -421,6 +435,7 @@ void Workspace::init()
|
|||
|
||||
Workspace::~Workspace()
|
||||
{
|
||||
finishCompositing();
|
||||
blockStackingUpdates( true );
|
||||
// TODO grabXServer();
|
||||
// use stacking_order, so that kwin --replace keeps stacking order
|
||||
|
@ -430,12 +445,12 @@ Workspace::~Workspace()
|
|||
{
|
||||
// only release the window
|
||||
(*it)->releaseWindow( true );
|
||||
// No removeClient() is called, it does more than just removing.
|
||||
// However, remove from some lists to e.g. prevent performTransiencyCheck()
|
||||
// from crashing.
|
||||
clients.remove( *it );
|
||||
desktops.remove( *it );
|
||||
// no removeClient() is called !
|
||||
}
|
||||
for( UnmanagedList::ConstIterator it = unmanaged.begin();
|
||||
it != unmanaged.end();
|
||||
++it )
|
||||
(*it)->release();
|
||||
delete desktop_widget;
|
||||
delete tab_box;
|
||||
delete popupinfo;
|
||||
|
@ -479,6 +494,28 @@ Client* Workspace::createClient( Window w, bool is_mapped )
|
|||
return NULL;
|
||||
}
|
||||
addClient( c, Allowed );
|
||||
if( scene )
|
||||
scene->windowAdded( c );
|
||||
if( effects )
|
||||
effects->windowAdded( c->effectWindow());
|
||||
return c;
|
||||
}
|
||||
|
||||
Unmanaged* Workspace::createUnmanaged( Window w )
|
||||
{
|
||||
if( w == overlay )
|
||||
return NULL;
|
||||
Unmanaged* c = new Unmanaged( this );
|
||||
if( !c->track( w ))
|
||||
{
|
||||
Unmanaged::deleteUnmanaged( c, Allowed );
|
||||
return NULL;
|
||||
}
|
||||
addUnmanaged( c, Allowed );
|
||||
if( scene )
|
||||
scene->windowAdded( c );
|
||||
if( effects )
|
||||
effects->windowAdded( c->effectWindow());
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -519,7 +556,11 @@ void Workspace::addClient( Client* c, allowed_t )
|
|||
updateStackingOrder( true ); // propagate new client
|
||||
if( c->isUtility() || c->isMenu() || c->isToolbar())
|
||||
updateToolWindows( true );
|
||||
checkNonExistentClients();
|
||||
}
|
||||
|
||||
void Workspace::addUnmanaged( Unmanaged* c, allowed_t )
|
||||
{
|
||||
unmanaged.append( c );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -576,6 +617,28 @@ void Workspace::removeClient( Client* c, allowed_t )
|
|||
updateClientArea();
|
||||
}
|
||||
|
||||
void Workspace::removeUnmanaged( Unmanaged* c, allowed_t )
|
||||
{
|
||||
assert( unmanaged.contains( c ));
|
||||
unmanaged.removeAll( c );
|
||||
}
|
||||
|
||||
void Workspace::addDeleted( Deleted* c, allowed_t )
|
||||
{
|
||||
assert( !deleted.contains( c ));
|
||||
deleted.append( c );
|
||||
}
|
||||
|
||||
void Workspace::removeDeleted( Deleted* c, allowed_t )
|
||||
{
|
||||
assert( deleted.contains( c ));
|
||||
if( scene )
|
||||
scene->windowDeleted( c );
|
||||
if( effects )
|
||||
effects->windowDeleted( c->effectWindow());
|
||||
deleted.removeAll( c );
|
||||
}
|
||||
|
||||
void Workspace::updateFocusChains( Client* c, FocusChainChange change )
|
||||
{
|
||||
if( !c->wantsTabFocus()) // doesn't want tab focus, remove
|
||||
|
@ -601,13 +664,7 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change )
|
|||
focus_chain[ i ].prepend( c );
|
||||
}
|
||||
else if( !focus_chain[ i ].contains( c ))
|
||||
{ // add it after the active one
|
||||
if( active_client != NULL && active_client != c
|
||||
&& !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
|
||||
focus_chain[ i ].insert( focus_chain[ i ].size() - 1, c );
|
||||
else
|
||||
focus_chain[ i ].append( c ); // otherwise add as the first one
|
||||
}
|
||||
focus_chain[ i ].prepend( c ); // otherwise add as the last one
|
||||
}
|
||||
}
|
||||
else //now only on desktop, remove it anywhere else
|
||||
|
@ -627,13 +684,7 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change )
|
|||
focus_chain[ i ].prepend( c );
|
||||
}
|
||||
else if( !focus_chain[ i ].contains( c ))
|
||||
{ // add it after the active one
|
||||
if( active_client != NULL && active_client != c
|
||||
&& !focus_chain[ i ].isEmpty() && focus_chain[ i ].last() == active_client )
|
||||
focus_chain[ i ].insert( focus_chain[ i ].size() - 1, c );
|
||||
else
|
||||
focus_chain[ i ].append( c ); // otherwise add as the first one
|
||||
}
|
||||
focus_chain[ i ].prepend( c );
|
||||
}
|
||||
else
|
||||
focus_chain[ i ].removeAll( c );
|
||||
|
@ -650,13 +701,7 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change )
|
|||
global_focus_chain.prepend( c );
|
||||
}
|
||||
else if( !global_focus_chain.contains( c ))
|
||||
{ // add it after the active one
|
||||
if( active_client != NULL && active_client != c
|
||||
&& !global_focus_chain.isEmpty() && global_focus_chain.last() == active_client )
|
||||
global_focus_chain.insert( global_focus_chain.size() - 1, c );
|
||||
else
|
||||
global_focus_chain.append( c ); // otherwise add as the first one
|
||||
}
|
||||
global_focus_chain.prepend( c );
|
||||
}
|
||||
|
||||
void Workspace::updateCurrentTopMenu()
|
||||
|
@ -874,11 +919,6 @@ void Workspace::updateColormap()
|
|||
}
|
||||
}
|
||||
|
||||
void Workspace::slotReloadConfig()
|
||||
{
|
||||
reconfigure();
|
||||
}
|
||||
|
||||
void Workspace::reconfigure()
|
||||
{
|
||||
reconfigureTimer.start( 200 );
|
||||
|
@ -895,7 +935,7 @@ void Workspace::slotSettingsChanged(int category)
|
|||
/*!
|
||||
Reread settings
|
||||
*/
|
||||
KWIN_PROCEDURE( CheckBorderSizesProcedure, cl->checkBorderSizes() );
|
||||
KWIN_PROCEDURE( CheckBorderSizesProcedure, Client, cl->checkBorderSizes() );
|
||||
|
||||
void Workspace::slotReconfigure()
|
||||
{
|
||||
|
@ -952,6 +992,11 @@ void Workspace::slotReconfigure()
|
|||
updateTopMenuGeometry();
|
||||
updateCurrentTopMenu();
|
||||
}
|
||||
|
||||
if( options->useTranslucency )
|
||||
setupCompositing();
|
||||
else
|
||||
finishCompositing();
|
||||
|
||||
loadWindowRules();
|
||||
for( ClientList::Iterator it = clients.begin();
|
||||
|
@ -1234,16 +1279,15 @@ bool Workspace::setCurrentDesktop( int new_desktop )
|
|||
// and active_client is on_all_desktops and under mouse (hence == old_active_client),
|
||||
// conserve focus (thanks to Volker Schatz <V.Schatz at thphys.uni-heidelberg.de>)
|
||||
else if( active_client && active_client->isShown( true ) && active_client->isOnCurrentDesktop())
|
||||
c = active_client;
|
||||
|
||||
if( c == NULL && !desktops.isEmpty())
|
||||
c = findDesktop( true, currentDesktop());
|
||||
c= active_client;
|
||||
|
||||
if( c != active_client )
|
||||
setActiveClient( NULL, Allowed );
|
||||
|
||||
if ( c )
|
||||
requestFocus( c );
|
||||
else if( !desktops.isEmpty() )
|
||||
requestFocus( findDesktop( true, currentDesktop()));
|
||||
else
|
||||
focusToNull();
|
||||
|
||||
|
@ -1265,6 +1309,10 @@ bool Workspace::setCurrentDesktop( int new_desktop )
|
|||
|
||||
if( old_desktop != 0 ) // not for the very first time
|
||||
popupinfo->showInfo( desktopName(currentDesktop()) );
|
||||
|
||||
if( effects != NULL && old_desktop != 0 )
|
||||
effects->desktopChanged( old_desktop );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1497,26 +1545,25 @@ void Workspace::sendClientToDesktop( Client* c, int desk, bool dont_activate )
|
|||
updateClientArea();
|
||||
}
|
||||
|
||||
void Workspace::setDesktopLayout(NET::Orientation o, int x, int y,NET::DesktopLayoutCorner c)
|
||||
void Workspace::setDesktopLayout(int o, int x, int y)
|
||||
{
|
||||
Q_UNUSED( c ); // I don't find this worth bothering, feel free to
|
||||
layoutOrientation = ( o == NET::OrientationHorizontal ? Qt::Horizontal : Qt::Vertical );
|
||||
layoutOrientation = (Qt::Orientation) o;
|
||||
layoutX = x;
|
||||
layoutY = y;
|
||||
}
|
||||
|
||||
void Workspace::calcDesktopLayout(int &x, int &y) const
|
||||
{
|
||||
x = layoutX; // <= 0 means compute it from the other and total number of desktops
|
||||
x = layoutX;
|
||||
y = layoutY;
|
||||
if((x <= 0) && (y > 0))
|
||||
if ((x == -1) && (y > 0))
|
||||
x = (numberOfDesktops()+y-1) / y;
|
||||
else if((y <=0) && (x > 0))
|
||||
else if ((y == -1) && (x > 0))
|
||||
y = (numberOfDesktops()+x-1) / x;
|
||||
|
||||
if(x <=0)
|
||||
if (x == -1)
|
||||
x = 1;
|
||||
if (y <= 0)
|
||||
if (y == -1)
|
||||
y = 1;
|
||||
}
|
||||
|
||||
|
@ -1648,7 +1695,7 @@ void Workspace::slotGrabWindow()
|
|||
QPixmap snapshot = QPixmap::grabWindow( active_client->frameId() );
|
||||
|
||||
//No XShape - no work.
|
||||
if( Shape::available())
|
||||
if( Extensions::shapeAvailable())
|
||||
{
|
||||
//As the first step, get the mask from XShape.
|
||||
int count, order;
|
||||
|
@ -1849,7 +1896,7 @@ bool Workspace::keyPressMouseEmulation( XKeyEvent& ev )
|
|||
bool is_alt = km & Mod1Mask;
|
||||
bool is_shift = km & ShiftMask;
|
||||
int delta = is_control?1:is_alt?32:8;
|
||||
QPoint pos = QCursor::pos();
|
||||
QPoint pos = cursorPos();
|
||||
|
||||
switch ( kc )
|
||||
{
|
||||
|
@ -2001,7 +2048,8 @@ void Workspace::createBorderWindows()
|
|||
XSetWindowAttributes attributes;
|
||||
unsigned long valuemask;
|
||||
attributes.override_redirect = True;
|
||||
attributes.event_mask = ( EnterWindowMask | LeaveWindowMask );
|
||||
attributes.event_mask = (EnterWindowMask | LeaveWindowMask |
|
||||
VisibilityChangeMask);
|
||||
valuemask= (CWOverrideRedirect | CWEventMask | CWCursor );
|
||||
attributes.cursor = XCreateFontCursor(display(),
|
||||
XC_sb_up_arrow);
|
||||
|
|
Loading…
Reference in a new issue