Improved the desktop grid effect.
FEATURE: 163104, 167265, 168557 CCBUG: 156247, 157196, 158787 svn path=/trunk/KDE/kdebase/workspace/; revision=845893
This commit is contained in:
parent
ff13bd5ed5
commit
fe4c100195
11 changed files with 1148 additions and 551 deletions
|
@ -229,7 +229,6 @@ Effects TODO
|
|||
/ desktopgrid
|
||||
+ - there's a bug that causes overlapping windows be shown also on desktops painted sooner than the window's desktop
|
||||
- needs clipping (and that probably needs support for cumulating clipping)
|
||||
! - make desktop borders distinctive (i.e. paint a grid), to make it more visible that desktops are still separate
|
||||
|
||||
|
||||
Performance
|
||||
|
|
|
@ -51,6 +51,7 @@ SET(kwin4_effect_builtins_sources
|
|||
shadow.cpp
|
||||
showfps.cpp
|
||||
showpaint.cpp
|
||||
slide.cpp
|
||||
taskbarthumbnail.cpp
|
||||
thumbnailaside.cpp
|
||||
zoom.cpp
|
||||
|
@ -74,6 +75,7 @@ install( FILES
|
|||
shadow.desktop
|
||||
showfps.desktop
|
||||
showpaint.desktop
|
||||
slide.desktop
|
||||
taskbarthumbnail.desktop
|
||||
thumbnailaside.desktop
|
||||
zoom.desktop
|
||||
|
@ -82,6 +84,7 @@ install( FILES
|
|||
# config modules
|
||||
SET(kwin4_effect_builtins_config_sources
|
||||
desktopgrid_config.cpp
|
||||
desktopgrid_config.ui
|
||||
diminactive_config.cpp
|
||||
diminactive_config.ui
|
||||
maketransparent_config.cpp
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -115,10 +115,10 @@ Comment[zh_TW]=將桌面以格狀佈局呈現的桌面切換器
|
|||
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=KWin/Effect
|
||||
X-KDE-PluginInfo-Author=Luboš Luňák
|
||||
X-KDE-PluginInfo-Email=l.lunak@kde.org
|
||||
X-KDE-PluginInfo-Author=Luboš Luňák & Lucas Murray
|
||||
X-KDE-PluginInfo-Email=l.lunak@kde.org & lmurray@undefinedfire.com
|
||||
X-KDE-PluginInfo-Name=kwin4_effect_desktopgrid
|
||||
X-KDE-PluginInfo-Version=0.1.0
|
||||
X-KDE-PluginInfo-Version=0.2.0
|
||||
X-KDE-PluginInfo-Category=Window Management
|
||||
X-KDE-PluginInfo-Depends=
|
||||
X-KDE-PluginInfo-License=GPL
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
|
||||
Copyright (C) 2008 Lucas Murray <lmurray@undefinedfire.com>
|
||||
|
||||
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
|
||||
|
@ -40,40 +41,50 @@ class DesktopGridEffect
|
|||
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void windowClosed( EffectWindow* w );
|
||||
virtual void desktopChanged( int old );
|
||||
virtual void windowInputMouseEvent( Window w, QEvent* e );
|
||||
virtual void grabbedKeyboardEvent( QKeyEvent* e );
|
||||
virtual bool borderActivated( ElectricBorder border );
|
||||
private slots:
|
||||
void toggle();
|
||||
private:
|
||||
QRect desktopRect( int desktop, bool scaled ) const;
|
||||
QPointF scalePos( const QPoint& pos, int desktop, int screen = -1 ) const;
|
||||
QPoint unscalePos( const QPoint& pos, int* desktop = NULL ) const;
|
||||
int posToDesktop( const QPoint& pos ) const;
|
||||
QRect windowRect( EffectWindow* w ) const; // returns always scaled
|
||||
EffectWindow* windowAt( const QPoint& pos, QRect* rect = NULL ) const;
|
||||
EffectWindow* windowAt( QPoint pos ) const;
|
||||
void setCurrentDesktop( int desktop );
|
||||
void setHighlightedDesktop( int desktop );
|
||||
void setActive( bool active );
|
||||
void setup();
|
||||
void finish();
|
||||
void paintSlide( int mask, QRegion region, const ScreenPaintData& data );
|
||||
void paintScreenDesktop( int desktop, int mask, QRegion region, ScreenPaintData data );
|
||||
void slideDesktopChanged( int old );
|
||||
void setHighlightedDesktop( int desktop );
|
||||
bool activated;
|
||||
TimeLine mTimeLine;
|
||||
int painting_desktop;
|
||||
int highlighted_desktop;
|
||||
Window input;
|
||||
bool keyboard_grab;
|
||||
bool was_window_move;
|
||||
EffectWindow* window_move;
|
||||
QPoint window_move_diff;
|
||||
QPoint window_move_pos;
|
||||
bool slideEnabled;
|
||||
bool slide;
|
||||
QPoint slide_start_pos;
|
||||
bool slide_painting_sticky;
|
||||
QPoint slide_painting_diff;
|
||||
|
||||
ElectricBorder borderActivate;
|
||||
int zoomDuration;
|
||||
int border;
|
||||
Qt::Alignment desktopNameAlignment;
|
||||
bool customLayout;
|
||||
int customLayoutRows;
|
||||
|
||||
bool activated;
|
||||
TimeLine timeline;
|
||||
int paintingDesktop;
|
||||
int highlightedDesktop;
|
||||
Window input;
|
||||
bool keyboardGrab;
|
||||
bool wasWindowMove;
|
||||
EffectWindow* windowMove;
|
||||
QPoint windowMoveDiff;
|
||||
|
||||
// Soft highlighting
|
||||
QList<TimeLine> hoverTimeline;
|
||||
|
||||
QSize gridSize;
|
||||
Qt::Orientation orientation;
|
||||
QPoint activeCell;
|
||||
// Per screen variables
|
||||
QList<double> scale; // Because the border isn't a ratio each screen is different
|
||||
QList<double> unscaledBorder;
|
||||
QList<QSizeF> scaledSize;
|
||||
QList<QPointF> scaledOffset;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
|
||||
Copyright (C) 2008 Lucas Murray <lmurray@undefinedfire.com>
|
||||
|
||||
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
|
||||
|
@ -19,123 +20,178 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*********************************************************************/
|
||||
|
||||
#include "desktopgrid_config.h"
|
||||
|
||||
#include <kwineffects.h>
|
||||
|
||||
#include <klocale.h>
|
||||
#include <kdebug.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <KActionCollection>
|
||||
#include <kaction.h>
|
||||
#include <KShortcutsEditor>
|
||||
#include <kconfiggroup.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QColor>
|
||||
#ifndef KDE_USE_FINAL
|
||||
KWIN_EFFECT_CONFIG_FACTORY
|
||||
#endif
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
DesktopGridEffectConfig::DesktopGridEffectConfig(QWidget* parent, const QVariantList& args) :
|
||||
KCModule(EffectFactory::componentData(), parent, args)
|
||||
DesktopGridEffectConfigForm::DesktopGridEffectConfigForm(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
}
|
||||
|
||||
DesktopGridEffectConfig::DesktopGridEffectConfig(QWidget* parent, const QVariantList& args)
|
||||
: KCModule( EffectFactory::componentData(), parent, args )
|
||||
{
|
||||
kDebug() ;
|
||||
m_ui = new DesktopGridEffectConfigForm( this );
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QVBoxLayout* layout = new QVBoxLayout( this );
|
||||
|
||||
mSlide = new QCheckBox(i18n("Animate desktop changes"), this);
|
||||
connect(mSlide, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||
layout->addWidget(mSlide);
|
||||
layout->addWidget( m_ui );
|
||||
|
||||
QHBoxLayout* comboLayout = new QHBoxLayout();
|
||||
QLabel* label = new QLabel(i18n("Activate when cursor is at a specific edge "
|
||||
"or corner of the screen:"), this);
|
||||
m_actionCollection = new KActionCollection( this, componentData() );
|
||||
m_actionCollection->setConfigGroup( "DesktopGrid" );
|
||||
m_actionCollection->setConfigGlobal( true );
|
||||
|
||||
mActivateCombo = new QComboBox;
|
||||
mActivateCombo->addItem(i18n("Top"));
|
||||
mActivateCombo->addItem(i18n("Top-right"));
|
||||
mActivateCombo->addItem(i18n("Right"));
|
||||
mActivateCombo->addItem(i18n("Bottom-right"));
|
||||
mActivateCombo->addItem(i18n("Bottom"));
|
||||
mActivateCombo->addItem(i18n("Bottom-left"));
|
||||
mActivateCombo->addItem(i18n("Left"));
|
||||
mActivateCombo->addItem(i18n("Top-left"));
|
||||
mActivateCombo->addItem(i18n("None"));
|
||||
connect(mActivateCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
|
||||
comboLayout->addWidget(label);
|
||||
comboLayout->addWidget(mActivateCombo);
|
||||
layout->addLayout(comboLayout);
|
||||
KAction* a = (KAction*) m_actionCollection->addAction( "ShowDesktopGrid" );
|
||||
a->setText( i18n( "Show Desktop Grid" ));
|
||||
a->setProperty( "isConfigurationAction", true );
|
||||
a->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::Key_F8 ));
|
||||
|
||||
KActionCollection* actionCollection = new KActionCollection( this, componentData() );
|
||||
KAction* show = static_cast<KAction*>(actionCollection->addAction( "ShowDesktopGrid" ));
|
||||
show->setText( i18n("Show Desktop Grid" ));
|
||||
show->setProperty("isConfigurationAction", true);
|
||||
show->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::Key_F8 ));
|
||||
m_ui->shortcutEditor->addCollection( m_actionCollection );
|
||||
|
||||
mShortcutEditor = new KShortcutsEditor(actionCollection, this,
|
||||
KShortcutsEditor::GlobalAction, KShortcutsEditor::LetterShortcutsDisallowed);
|
||||
connect(mShortcutEditor, SIGNAL(keyChange()), this, SLOT(changed()));
|
||||
layout->addWidget(mShortcutEditor);
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Top" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Top-right" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Right" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Bottom-right" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Bottom" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Bottom-left" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Left" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "Top-left" ));
|
||||
m_ui->screenEdgeCombo->addItem( i18n( "None" ));
|
||||
|
||||
layout->addStretch();
|
||||
m_alignmentItems.append( Qt::Alignment( 0 ));
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Disabled" ));
|
||||
m_alignmentItems.append( Qt::AlignHCenter | Qt::AlignTop );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Top" ));
|
||||
m_alignmentItems.append( Qt::AlignRight | Qt::AlignTop );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Top-right" ));
|
||||
m_alignmentItems.append( Qt::AlignRight | Qt::AlignVCenter );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Right" ));
|
||||
m_alignmentItems.append( Qt::AlignRight | Qt::AlignBottom );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Bottom-right" ));
|
||||
m_alignmentItems.append( Qt::AlignHCenter | Qt::AlignBottom );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Bottom" ));
|
||||
m_alignmentItems.append( Qt::AlignLeft | Qt::AlignBottom );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Bottom-left" ));
|
||||
m_alignmentItems.append( Qt::AlignLeft | Qt::AlignVCenter );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Left" ));
|
||||
m_alignmentItems.append( Qt::AlignLeft | Qt::AlignTop );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Top-left" ));
|
||||
m_alignmentItems.append( Qt::AlignCenter );
|
||||
m_ui->desktopNameAlignmentCombo->addItem( i18n( "Center" ));
|
||||
|
||||
connect( m_ui->screenEdgeCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
|
||||
connect( m_ui->zoomDurationSpin, SIGNAL( valueChanged( int )), this, SLOT( changed() ));
|
||||
connect( m_ui->borderWidthSpin, SIGNAL( valueChanged( int )), this, SLOT( changed() ));
|
||||
connect( m_ui->desktopNameAlignmentCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
|
||||
connect( m_ui->layoutBox, SIGNAL( stateChanged( int )), this, SLOT( changed() ));
|
||||
connect( m_ui->layoutBox, SIGNAL( stateChanged( int )), this, SLOT( layoutSelectionChanged() ));
|
||||
connect( m_ui->layoutRowsSpin, SIGNAL( valueChanged( int )), this, SLOT( changed() ));
|
||||
connect( m_ui->shortcutEditor, SIGNAL( keyChange() ), this, SLOT( changed() ));
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
DesktopGridEffectConfig::~DesktopGridEffectConfig()
|
||||
{
|
||||
kDebug();
|
||||
// Undo (only) unsaved changes to global key shortcuts
|
||||
mShortcutEditor->undoChanges();
|
||||
// If save() is called undoChanges() has no effect
|
||||
m_ui->shortcutEditor->undoChanges();
|
||||
}
|
||||
|
||||
void DesktopGridEffectConfig::load()
|
||||
{
|
||||
kDebug();
|
||||
KCModule::load();
|
||||
|
||||
KConfigGroup conf = EffectsHandler::effectConfig("DesktopGrid");
|
||||
mSlide->setChecked(conf.readEntry("Slide", true));
|
||||
|
||||
int activateBorder = conf.readEntry("BorderActivate", (int)ElectricNone);
|
||||
if(activateBorder == (int)ElectricNone)
|
||||
KConfigGroup conf = EffectsHandler::effectConfig( "DesktopGrid" );
|
||||
|
||||
int activateBorder = conf.readEntry( "BorderActivate", int( ElectricNone ));
|
||||
if( activateBorder == int( ElectricNone ))
|
||||
activateBorder--;
|
||||
mActivateCombo->setCurrentIndex(activateBorder);
|
||||
m_ui->screenEdgeCombo->setCurrentIndex( activateBorder );
|
||||
|
||||
m_ui->zoomDurationSpin->setValue( conf.readEntry( "ZoomDuration", 500 ));
|
||||
m_ui->borderWidthSpin->setValue( conf.readEntry( "BorderWidth", 10 ));
|
||||
|
||||
Qt::Alignment alignment = Qt::Alignment( conf.readEntry( "DesktopNameAlignment", 0 ));
|
||||
m_ui->desktopNameAlignmentCombo->setCurrentIndex( m_alignmentItems.indexOf( alignment ));
|
||||
|
||||
if( conf.readEntry( "CustomLayout", false ))
|
||||
m_ui->layoutBox->setCheckState( Qt::Checked );
|
||||
else
|
||||
m_ui->layoutBox->setCheckState( Qt::Unchecked );
|
||||
layoutSelectionChanged();
|
||||
|
||||
m_ui->layoutRowsSpin->setValue( conf.readEntry( "CustomLayoutRows", 2 ));
|
||||
|
||||
emit changed(false);
|
||||
}
|
||||
|
||||
void DesktopGridEffectConfig::save()
|
||||
{
|
||||
kDebug() ;
|
||||
KCModule::save();
|
||||
|
||||
KConfigGroup conf = EffectsHandler::effectConfig("DesktopGrid");
|
||||
conf.writeEntry("Slide", mSlide->isChecked());
|
||||
KConfigGroup conf = EffectsHandler::effectConfig( "DesktopGrid" );
|
||||
|
||||
int activateBorder = m_ui->screenEdgeCombo->currentIndex();
|
||||
if( activateBorder == int( ELECTRIC_COUNT ))
|
||||
activateBorder = int( ElectricNone );
|
||||
conf.writeEntry( "BorderActivate", activateBorder );
|
||||
|
||||
conf.writeEntry( "ZoomDuration", m_ui->zoomDurationSpin->value() );
|
||||
conf.writeEntry( "BorderWidth", m_ui->borderWidthSpin->value() );
|
||||
|
||||
int alignment = m_ui->desktopNameAlignmentCombo->currentIndex();
|
||||
alignment = int( m_alignmentItems[alignment] );
|
||||
conf.writeEntry( "DesktopNameAlignment", alignment );
|
||||
|
||||
conf.writeEntry( "CustomLayout", m_ui->layoutBox->checkState() == Qt::Checked ? 1 : 0 );
|
||||
conf.writeEntry( "CustomLayoutRows", m_ui->layoutRowsSpin->value() );
|
||||
|
||||
m_ui->shortcutEditor->save();
|
||||
|
||||
int activateBorder = mActivateCombo->currentIndex();
|
||||
if(activateBorder == (int)ELECTRIC_COUNT)
|
||||
activateBorder = (int)ElectricNone;
|
||||
conf.writeEntry("BorderActivate", activateBorder);
|
||||
conf.sync();
|
||||
|
||||
mShortcutEditor->save(); // undo() will restore to this state from now on
|
||||
|
||||
emit changed(false);
|
||||
EffectsHandler::sendReloadMessage( "desktopgrid" );
|
||||
}
|
||||
|
||||
void DesktopGridEffectConfig::defaults()
|
||||
{
|
||||
kDebug() ;
|
||||
mSlide->setChecked(true);
|
||||
mActivateCombo->setCurrentIndex( (int)ElectricNone -1 );
|
||||
mShortcutEditor->allDefault();
|
||||
m_ui->screenEdgeCombo->setCurrentIndex( int( ElectricNone - 1 ));
|
||||
m_ui->zoomDurationSpin->setValue( 500 );
|
||||
m_ui->borderWidthSpin->setValue( 10 );
|
||||
m_ui->desktopNameAlignmentCombo->setCurrentIndex( 0 );
|
||||
m_ui->layoutBox->setCheckState( Qt::Unchecked );
|
||||
m_ui->layoutRowsSpin->setValue( 2 );
|
||||
m_ui->shortcutEditor->allDefault();
|
||||
emit changed(true);
|
||||
}
|
||||
|
||||
void DesktopGridEffectConfig::layoutSelectionChanged()
|
||||
{
|
||||
if( m_ui->layoutBox->checkState() == Qt::Checked )
|
||||
{
|
||||
m_ui->layoutRowsLabel->setEnabled( true );
|
||||
m_ui->layoutRowsSpin->setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->layoutRowsLabel->setEnabled( false );
|
||||
m_ui->layoutRowsSpin->setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "desktopgrid_config.moc"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
|
||||
Copyright (C) 2008 Lucas Murray <lmurray@undefinedfire.com>
|
||||
|
||||
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
|
||||
|
@ -23,13 +24,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <kcmodule.h>
|
||||
|
||||
class QComboBox;
|
||||
class QCheckBox;
|
||||
class KShortcutsEditor;
|
||||
#include "ui_desktopgrid_config.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class DesktopGridEffectConfigForm : public QWidget, public Ui::DesktopGridEffectConfigForm
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DesktopGridEffectConfigForm(QWidget* parent);
|
||||
};
|
||||
|
||||
class DesktopGridEffectConfig : public KCModule
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -42,10 +48,13 @@ class DesktopGridEffectConfig : public KCModule
|
|||
virtual void load();
|
||||
virtual void defaults();
|
||||
|
||||
private slots:
|
||||
void layoutSelectionChanged();
|
||||
|
||||
private:
|
||||
QCheckBox* mSlide;
|
||||
QComboBox* mActivateCombo;
|
||||
KShortcutsEditor *mShortcutEditor;
|
||||
DesktopGridEffectConfigForm* m_ui;
|
||||
KActionCollection* m_actionCollection;
|
||||
QList<Qt::Alignment> m_alignmentItems;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
178
effects/desktopgrid_config.ui
Normal file
178
effects/desktopgrid_config.ui
Normal file
|
@ -0,0 +1,178 @@
|
|||
<ui version="4.0" >
|
||||
<class>KWin::DesktopGridEffectConfigForm</class>
|
||||
<widget class="QWidget" name="KWin::DesktopGridEffectConfigForm" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>508</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" >
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<string>Appearance</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3" >
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Zoom &duration:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>zoomDurationSpin</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QSpinBox" name="zoomDurationSpin" >
|
||||
<property name="suffix" >
|
||||
<string> msec</string>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="value" >
|
||||
<number>500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" >
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="text" >
|
||||
<string>&Border width:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>borderWidthSpin</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" >
|
||||
<widget class="QSpinBox" name="borderWidthSpin" >
|
||||
<property name="suffix" >
|
||||
<string> pixels</string>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value" >
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" >
|
||||
<widget class="QLabel" name="label_6" >
|
||||
<property name="text" >
|
||||
<string>Desktop &name alignment:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>desktopNameAlignmentCombo</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" >
|
||||
<widget class="QComboBox" name="desktopNameAlignmentCombo" />
|
||||
</item>
|
||||
<item row="7" column="0" >
|
||||
<widget class="QCheckBox" name="layoutBox" >
|
||||
<property name="text" >
|
||||
<string>Custom grid &layout</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" >
|
||||
<widget class="QLabel" name="layoutRowsLabel" >
|
||||
<property name="text" >
|
||||
<string>Number of &rows:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>layoutRowsSpin</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1" >
|
||||
<widget class="QSpinBox" name="layoutRowsSpin" >
|
||||
<property name="suffix" >
|
||||
<string> rows</string>
|
||||
</property>
|
||||
<property name="minimum" >
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="value" >
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2" >
|
||||
<spacer name="verticalSpacer" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2" >
|
||||
<property name="title" >
|
||||
<string>Activation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<string>Active screen &edge:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>screenEdgeCombo</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QComboBox" name="screenEdgeCombo" />
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2" >
|
||||
<widget class="KWin::GlobalShortcutsEditor" native="1" name="shortcutEditor" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KWin::GlobalShortcutsEditor</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global" >kwineffects.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>zoomDurationSpin</tabstop>
|
||||
<tabstop>borderWidthSpin</tabstop>
|
||||
<tabstop>desktopNameAlignmentCombo</tabstop>
|
||||
<tabstop>layoutBox</tabstop>
|
||||
<tabstop>layoutRowsSpin</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
266
effects/slide.cpp
Normal file
266
effects/slide.cpp
Normal file
|
@ -0,0 +1,266 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
|
||||
Copyright (C) 2008 Lucas Murray <admin@undefinedfire.com>
|
||||
|
||||
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, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#include "slide.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
KWIN_EFFECT( slide, SlideEffect )
|
||||
|
||||
SlideEffect::SlideEffect()
|
||||
: slide( false )
|
||||
{
|
||||
mTimeLine.setCurveShape(TimeLine::EaseInOutCurve);
|
||||
}
|
||||
|
||||
void SlideEffect::prePaintScreen( ScreenPrePaintData& data, int time )
|
||||
{
|
||||
if( slide )
|
||||
{
|
||||
mTimeLine.addTime(time);
|
||||
|
||||
// PAINT_SCREEN_BACKGROUND_FIRST is needed because screen will be actually painted more than once,
|
||||
// so with normal screen painting second screen paint would erase parts of the first paint
|
||||
if( mTimeLine.value() != 1 )
|
||||
data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST;
|
||||
else
|
||||
{
|
||||
slide = false;
|
||||
mTimeLine.setProgress(0);
|
||||
}
|
||||
}
|
||||
effects->prePaintScreen( data, time );
|
||||
}
|
||||
|
||||
void SlideEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
|
||||
{
|
||||
if( slide )
|
||||
{
|
||||
if( w->isOnAllDesktops())
|
||||
{
|
||||
if( slide_painting_sticky )
|
||||
data.setTransformed();
|
||||
else
|
||||
w->disablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
||||
}
|
||||
else if( w->isOnDesktop( painting_desktop ))
|
||||
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
||||
else
|
||||
w->disablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP );
|
||||
}
|
||||
effects->prePaintWindow( w, data, time );
|
||||
}
|
||||
|
||||
void SlideEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
||||
{
|
||||
if( mTimeLine.value() == 0 )
|
||||
{
|
||||
effects->paintScreen( mask, region, data );
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Transformations are done by remembering starting position of the change and the progress
|
||||
of it, the destination is computed from the current desktop. Positions of desktops
|
||||
are done using their topleft corner.
|
||||
*/
|
||||
QPoint destPos = desktopRect( effects->currentDesktop(), false ).topLeft();
|
||||
QPoint diffPos = destPos - slide_start_pos;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
if( effects->optionRollOverDesktops())
|
||||
{
|
||||
int x, y;
|
||||
Qt::Orientation orientation;
|
||||
effects->calcDesktopLayout( &x, &y, &orientation );
|
||||
w = x * displayWidth();
|
||||
h = y * displayHeight();
|
||||
// wrap around if shorter
|
||||
if( diffPos.x() > 0 && diffPos.x() > w / 2 )
|
||||
diffPos.setX( diffPos.x() - w );
|
||||
if( diffPos.x() < 0 && abs( diffPos.x()) > w / 2 )
|
||||
diffPos.setX( diffPos.x() + w );
|
||||
if( diffPos.y() > 0 && diffPos.y() > h / 2 )
|
||||
diffPos.setY( diffPos.y() - h );
|
||||
if( diffPos.y() < 0 && abs( diffPos.y()) > h / 2 )
|
||||
diffPos.setY( diffPos.y() + h );
|
||||
}
|
||||
QPoint currentPos = slide_start_pos + mTimeLine.value() * diffPos;
|
||||
QSize displaySize( displayWidth(), displayHeight());
|
||||
QRegion currentRegion = QRect( currentPos, displaySize );
|
||||
if( effects->optionRollOverDesktops())
|
||||
{
|
||||
currentRegion |= ( currentRegion & QRect( -w, 0, w, h )).translated( w, 0 );
|
||||
currentRegion |= ( currentRegion & QRect( 0, -h, w, h )).translated( 0, h );
|
||||
currentRegion |= ( currentRegion & QRect( w, 0, w, h )).translated( -w, 0 );
|
||||
currentRegion |= ( currentRegion & QRect( 0, h, w, h )).translated( 0, -h );
|
||||
}
|
||||
bool do_sticky = true;
|
||||
for( int desktop = 1;
|
||||
desktop <= effects->numberOfDesktops();
|
||||
++desktop )
|
||||
{
|
||||
QRect rect = desktopRect( desktop, false );
|
||||
if( currentRegion.contains( rect )) // part of the desktop needs painting
|
||||
{
|
||||
painting_desktop = desktop;
|
||||
slide_painting_sticky = do_sticky;
|
||||
slide_painting_diff = rect.topLeft() - currentPos;
|
||||
if( effects->optionRollOverDesktops())
|
||||
{
|
||||
if( slide_painting_diff.x() > displayWidth())
|
||||
slide_painting_diff.setX( slide_painting_diff.x() - w );
|
||||
if( slide_painting_diff.x() < -displayWidth())
|
||||
slide_painting_diff.setX( slide_painting_diff.x() + w );
|
||||
if( slide_painting_diff.y() > displayHeight())
|
||||
slide_painting_diff.setY( slide_painting_diff.y() - h );
|
||||
if( slide_painting_diff.y() < -displayHeight())
|
||||
slide_painting_diff.setY( slide_painting_diff.y() + h );
|
||||
}
|
||||
do_sticky = false; // paint on-all-desktop windows only once
|
||||
ScreenPaintData d = data;
|
||||
d.xTranslate += slide_painting_diff.x();
|
||||
d.yTranslate += slide_painting_diff.y();
|
||||
// TODO mask parts that are not visible?
|
||||
effects->paintScreen( mask, region, d );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SlideEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
{
|
||||
if( slide )
|
||||
{ // don't move windows on all desktops (compensate screen transformation)
|
||||
if( w->isOnAllDesktops()) // TODO also fix 'Workspace::movingClient'
|
||||
{
|
||||
data.xTranslate -= slide_painting_diff.x();
|
||||
data.yTranslate -= slide_painting_diff.y();
|
||||
}
|
||||
}
|
||||
effects->paintWindow( w, mask, region, data );
|
||||
}
|
||||
|
||||
void SlideEffect::postPaintScreen()
|
||||
{
|
||||
if( slide )
|
||||
effects->addRepaintFull();
|
||||
effects->postPaintScreen();
|
||||
}
|
||||
|
||||
// Gives a position of the given desktop when all desktops are arranged in a grid
|
||||
QRect SlideEffect::desktopRect( int desktop, bool scaled ) const
|
||||
{
|
||||
int x, y;
|
||||
Qt::Orientation orientation;
|
||||
effects->calcDesktopLayout( &x, &y, &orientation );
|
||||
--desktop; // make it start with 0
|
||||
QRect rect;
|
||||
if( orientation == Qt::Horizontal )
|
||||
rect = QRect(( desktop % x ) * displayWidth(), ( desktop / x ) * displayHeight(),
|
||||
displayWidth(), displayHeight());
|
||||
else
|
||||
rect = QRect(( desktop / y ) * displayWidth(), ( desktop % y ) * displayHeight(),
|
||||
displayWidth(), displayHeight());
|
||||
if( !scaled )
|
||||
return rect;
|
||||
QRect current = desktopRect( effects->currentDesktop(), false );
|
||||
double progress = mTimeLine.value();
|
||||
rect = QRect( qRound( interpolate( rect.x() - current.x(), rect.x() / double( x ), progress )),
|
||||
qRound( interpolate( rect.y() - current.y(), rect.y() / double( y ), progress )),
|
||||
qRound( interpolate( rect.width(), displayWidth() / double( x ), progress )),
|
||||
qRound( interpolate( rect.height(), displayHeight() / double( y ), progress )));
|
||||
return rect;
|
||||
}
|
||||
|
||||
void SlideEffect::desktopChanged( int old )
|
||||
{
|
||||
if( effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this )
|
||||
return;
|
||||
|
||||
if( slide ) // old slide still in progress
|
||||
{
|
||||
QPoint diffPos = desktopRect( old, false ).topLeft() - slide_start_pos;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
if( effects->optionRollOverDesktops())
|
||||
{
|
||||
int x, y;
|
||||
Qt::Orientation orientation;
|
||||
effects->calcDesktopLayout( &x, &y, &orientation );
|
||||
w = x * displayWidth();
|
||||
h = y * displayHeight();
|
||||
// wrap around if shorter
|
||||
if( diffPos.x() > 0 && diffPos.x() > w / 2 )
|
||||
diffPos.setX( diffPos.x() - w );
|
||||
if( diffPos.x() < 0 && abs( diffPos.x()) > w / 2 )
|
||||
diffPos.setX( diffPos.x() + w );
|
||||
if( diffPos.y() > 0 && diffPos.y() > h / 2 )
|
||||
diffPos.setY( diffPos.y() - h );
|
||||
if( diffPos.y() < 0 && abs( diffPos.y()) > h / 2 )
|
||||
diffPos.setY( diffPos.y() + h );
|
||||
}
|
||||
QPoint currentPos = slide_start_pos + mTimeLine.value() * diffPos;
|
||||
QRegion currentRegion = QRect( currentPos, QSize( displayWidth(), displayHeight()));
|
||||
if( effects->optionRollOverDesktops())
|
||||
{
|
||||
currentRegion |= ( currentRegion & QRect( -w, 0, w, h )).translated( w, 0 );
|
||||
currentRegion |= ( currentRegion & QRect( 0, -h, w, h )).translated( 0, h );
|
||||
currentRegion |= ( currentRegion & QRect( w, 0, w, h )).translated( -w, 0 );
|
||||
currentRegion |= ( currentRegion & QRect( 0, h, w, h )).translated( 0, -h );
|
||||
}
|
||||
QRect rect = desktopRect( effects->currentDesktop(), false );
|
||||
if( currentRegion.contains( rect ))
|
||||
{ // current position is in new current desktop (e.g. quickly changing back),
|
||||
// don't do full progress
|
||||
if( abs( currentPos.x() - rect.x()) > abs( currentPos.y() - rect.y()))
|
||||
mTimeLine.setProgress(1 - abs( currentPos.x() - rect.x()) / double( displayWidth()));
|
||||
else
|
||||
mTimeLine.setProgress(1 - abs( currentPos.y() - rect.y()) / double( displayHeight()));
|
||||
}
|
||||
else // current position is not on current desktop, do full progress
|
||||
mTimeLine.setProgress(0);
|
||||
diffPos = rect.topLeft() - currentPos;
|
||||
if( mTimeLine.value() <= 0 )
|
||||
{
|
||||
// Compute starting point for this new move (given current and end positions)
|
||||
slide_start_pos = rect.topLeft() - diffPos * 1 / ( 1 - mTimeLine.value() );
|
||||
}
|
||||
else
|
||||
{ // at the end, stop
|
||||
slide = false;
|
||||
mTimeLine.setProgress(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mTimeLine.setProgress(0);
|
||||
slide_start_pos = desktopRect( old, false ).topLeft();
|
||||
slide = true;
|
||||
}
|
||||
effects->addRepaintFull();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "slide.moc"
|
17
effects/slide.desktop
Normal file
17
effects/slide.desktop
Normal file
|
@ -0,0 +1,17 @@
|
|||
[Desktop Entry]
|
||||
Name=Slide
|
||||
Icon=preferences-system-windows-effect-slide
|
||||
Comment=Slide windows when switching desktops
|
||||
|
||||
Type=Service
|
||||
X-KDE-ServiceTypes=KWin/Effect
|
||||
X-KDE-PluginInfo-Author=Luboš Luňák
|
||||
X-KDE-PluginInfo-Email=l.lunak@kde.org
|
||||
X-KDE-PluginInfo-Name=kwin4_effect_slide
|
||||
X-KDE-PluginInfo-Version=0.1.0
|
||||
X-KDE-PluginInfo-Category=Appearance
|
||||
X-KDE-PluginInfo-Depends=
|
||||
X-KDE-PluginInfo-License=GPL
|
||||
X-KDE-PluginInfo-EnabledByDefault=true
|
||||
X-KDE-Library=kwin4_effect_builtins
|
||||
X-KDE-Ordering=50
|
56
effects/slide.h
Normal file
56
effects/slide.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
|
||||
Copyright (C) 2008 Lucas Murray <admin@undefinedfire.com>
|
||||
|
||||
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, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef KWIN_SLIDE_H
|
||||
#define KWIN_SLIDE_H
|
||||
|
||||
#include <kwineffects.h>
|
||||
#include <QObject>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class SlideEffect
|
||||
: public QObject, public Effect
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SlideEffect();
|
||||
virtual void prePaintScreen( ScreenPrePaintData& data, int time );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void postPaintScreen();
|
||||
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void desktopChanged( int old );
|
||||
private:
|
||||
QRect desktopRect( int desktop, bool scaled ) const;
|
||||
TimeLine mTimeLine;
|
||||
int painting_desktop;
|
||||
bool slide;
|
||||
QPoint slide_start_pos;
|
||||
bool slide_painting_sticky;
|
||||
QPoint slide_painting_diff;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue