add windowgeometry tip effect, bind it to the general setting and generalize effect feature provide api, thus update resize effect

BUG: 219755

svn path=/trunk/KDE/kdebase/workspace/; revision=1195300
This commit is contained in:
Thomas Lübking 2010-11-10 19:21:56 +00:00
parent 6353d6ff57
commit 68fbd31ad8
17 changed files with 512 additions and 9 deletions

View file

@ -228,10 +228,10 @@ void EffectsHandlerImpl::postPaintWindow( EffectWindow* w )
// no special final code
}
bool EffectsHandlerImpl::providesResizeEffect()
bool EffectsHandlerImpl::provides( Effect::Feature ef )
{
for( int i = 0; i < loaded_effects.size(); ++i )
if( loaded_effects.at(i).second->isResizeEffect() )
if( loaded_effects.at(i).second->provides( ef ) )
return true;
return false;
}

View file

@ -48,7 +48,7 @@ class EffectsHandlerImpl : public EffectsHandler
virtual void postPaintWindow( EffectWindow* w );
virtual void paintEffectFrame( EffectFrame* frame, QRegion region, double opacity, double frameOpacity );
bool providesResizeEffect();
bool provides( Effect::Feature ef );
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );

View file

@ -81,6 +81,7 @@ include( slideback/CMakeLists.txt )
include( slidingpopups/CMakeLists.txt )
include( taskbarthumbnail/CMakeLists.txt )
include( thumbnailaside/CMakeLists.txt )
include( windowgeometry/CMakeLists.txt )
include( zoom/CMakeLists.txt )
# OpenGL-specific effects

View file

@ -61,7 +61,7 @@ Name[x-test]=xxResize Windowxx
Name[zh_CN]=
Name[zh_TW]=調
Icon=preferences-system-windows-effect-resize
Comment=Effect to outline geometry while resizing a window
Comment=Resizes windows with a fast texture scale instead of updating contents
Comment[ar]=تأثير لإظهار شكل النافذة الأصلي أثناء تغيير حجمها
Comment[ast]=Efeutu pa dibuxar la xeometría al camudar el tamañu d'una ventana
Comment[ca]=Efecte de geometria de contorn en redimensionar una finestra

View file

@ -32,7 +32,7 @@ class ResizeEffect
public:
ResizeEffect();
~ResizeEffect();
virtual inline bool isResizeEffect() { return true; }
virtual inline bool provides( Effect::Feature ef ) { return ef == Effect::Resize; }
virtual void prePaintScreen( ScreenPrePaintData& data, int time );
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );

View file

@ -0,0 +1,26 @@
#######################################
# Effect
# Source files
set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources}
windowgeometry/windowgeometry.cpp
)
# .desktop files
install( FILES
windowgeometry/windowgeometry.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
#######################################
# Config
# Source files
set( kwin4_effect_builtins_config_sources ${kwin4_effect_builtins_config_sources}
windowgeometry/windowgeometry_config.cpp
windowgeometry/windowgeometry_config.ui
)
# .desktop files
install( FILES
windowgeometry/windowgeometry_config.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin )

View file

@ -0,0 +1,179 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2010 Thomas Lübking <thomas.luebking@web.de>
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 "windowgeometry.h"
#include <QStringBuilder>
#include <kwinconfig.h>
#include <kconfiggroup.h>
#include <kwindowsystem.h>
#include <KActionCollection>
#include <kaction.h>
using namespace KWin;
KWIN_EFFECT( windowgeometry, WindowGeometry )
WindowGeometry::WindowGeometry()
{
iAmActivated = true;
iAmActive = false;
myResizeWindow = 0L;
myResizeString = i18nc("Window geometry display, %1 and %2 are the new size,"
" %3 and %4 are pixel increments - avoid reformatting or suffixes like 'px'",
"Width: %1 (%3)\nHeight: %2 (%4)");
myCoordString[0] = i18nc("Window geometry display, %1 and %2 are the cartesian x and y coordinates"
" - avoid reformatting or suffixes like 'px'",
"X: %1\nY: %2");
myCoordString[1] = i18nc("Window geometry display, %1 and %2 are the cartesian x and y coordinates,"
" %3 and %4 are the resp. increments - avoid reformatting or suffixes like 'px'",
"X: %1 (%3)\nY: %2 (%4)");
reconfigure( ReconfigureAll );
QFont fnt; fnt.setBold(true); fnt.setPointSize(12);
for ( int i = 0; i < 3; ++i )
{
myMeasure[i] = effects->effectFrame( EffectFrameUnstyled, false );
myMeasure[i]->setFont( fnt );
}
myMeasure[0]->setAlignment( Qt::AlignLeft|Qt::AlignTop );
myMeasure[1]->setAlignment( Qt::AlignCenter );
myMeasure[2]->setAlignment( Qt::AlignRight|Qt::AlignBottom );
KActionCollection* actionCollection = new KActionCollection( this );
KAction* a = static_cast< KAction* >( actionCollection->addAction( "WindowGeometry" ));
a->setText( i18n("Toggle window geometry display (effect only)" ));
a->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::SHIFT + Qt::Key_F11 ));
connect( a, SIGNAL( triggered(bool) ), this, SLOT( toggle() ) );
}
WindowGeometry::~WindowGeometry()
{
for ( int i = 0; i < 3; ++i )
delete myMeasure[i];
}
void WindowGeometry::reconfigure( ReconfigureFlags )
{
KConfigGroup conf = effects->effectConfig( "WindowGeometry" );
iHandleMoves = conf.readEntry( "Move", true );
iHandleResizes = conf.readEntry( "Resize", true );
}
void WindowGeometry::paintScreen(int mask, QRegion region, ScreenPaintData &data)
{
effects->paintScreen( mask, region, data );
if ( iAmActivated && iAmActive )
{
for ( int i = 0; i < 3; ++i )
myMeasure[i]->render(infiniteRegion(), 1.0, .66);
}
}
void WindowGeometry::toggle()
{
iAmActivated = !iAmActivated;
}
void WindowGeometry::windowUserMovedResized( EffectWindow* w, bool first, bool last )
{
if (first && last) // "maximized"
return;
if ( first )
{
if ( !iAmActivated )
return;
if ( w->isUserResize() && !iHandleResizes )
return;
if ( w->isUserMove() && !iHandleMoves)
return;
iAmActive = true;
myResizeWindow = w;
myOriginalGeometry = w->geometry();
myCurrentGeometry = w->geometry();
effects->addRepaint( myCurrentGeometry.adjusted(-20, -20, 20, 20) );
}
if ( iAmActive && w == myResizeWindow && last )
{
iAmActive = false;
myResizeWindow = 0L;
effects->addRepaint( myCurrentGeometry.adjusted(-20, -20, 20, 20) );
}
}
static inline QString number(int n)
{
if ( n >= 0 )
return "+" + QString::number(n);
return QString::number(n); // "-" is auto-applied
}
void WindowGeometry::windowMoveResizeGeometryUpdate( EffectWindow* w, const QRect& geometry )
{
if ( iAmActivated && iAmActive && w == myResizeWindow )
{
myCurrentGeometry = geometry;
const QRect &r = geometry;
const QRect &r2 = myOriginalGeometry;
// sufficient for moves, resizes calculated otherwise
int dx = r.x() - r2.x();
int dy = r.y() - r2.y();
// upper left ----------------------
if ( w->isUserResize() )
myMeasure[0]->setText( myCoordString[1].arg( r.x() ).arg( r.y() ).arg( number(dx) ).arg( number(dy) ) );
else
myMeasure[0]->setText( myCoordString[0].arg( r.x() ).arg( r.y() ) );
myMeasure[0]->setPosition( geometry.topLeft() );
// center ----------------------
if ( w->isUserResize() )
{
// calc width for center element, otherwise the current dx/dx remains right
dx = r.width() - r2.width();
dy = r.height() - r2.height();
// TODO: i hate this. anyone got a nice idea to invoke the stringbuilder or otherwise avoid
// dogslow QString::arg() system here?
myMeasure[1]->setText( myResizeString.arg( r.width() ).arg( r.height() ).arg( number(dx) ).arg( number(dy) ) );
// calc width for bottomright element, superflous otherwise
dx = r.right() - r2.right();
dy = r.bottom() - r2.bottom();
}
else
myMeasure[1]->setText( myCoordString[0].arg( number(dx) ).arg( number(dy) ) );
myMeasure[1]->setPosition( geometry.center() );
// lower right ----------------------
if ( w->isUserResize() )
myMeasure[2]->setText( myCoordString[1].arg( r.right() ).arg( r.bottom() ).arg( number(dx) ).arg( number(dy) ) );
else
myMeasure[2]->setText( myCoordString[0].arg( r.right() ).arg( r.bottom() ) );
myMeasure[2]->setPosition( geometry.bottomRight() );
effects->addRepaint( geometry.adjusted(-20, -20, 20, 20) );
}
}

View file

@ -0,0 +1,28 @@
[Desktop Entry]
# Name of the effect
Name=WindowGeometry
Comment=Display window geometries on move/resize
Icon=preferences-system-windows-effect-windowgeometry
# This is KWin effect
Type=Service
X-KDE-ServiceTypes=KWin/Effect
# Author and email of the author
X-KDE-PluginInfo-Author=Thomas Lübking
X-KDE-PluginInfo-Email=thomas.luebking@web.de
# Internal name of the effect
X-KDE-PluginInfo-Name=kwin4_effect_windowgeometry
# Category of the effect, for config dialog
X-KDE-PluginInfo-Category=Appearance
# Version and license
X-KDE-PluginInfo-Version=0.1
X-KDE-PluginInfo-License=GPL
# If the effect depends on any other effect(s) to be active, then internal
# names of those effects can be given here
X-KDE-PluginInfo-Depends=
# Whether this effect should be enabled by default
X-KDE-PluginInfo-EnabledByDefault=false
# The plugin (library) which contains the effect. One library may contain more effects.
X-KDE-Library=kwin4_effect_builtins
# The order in which this effect is loaded. Lower numbers are loaded first.
X-KDE-Ordering=90

View file

@ -0,0 +1,54 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2010 Thomas Lübking <thomas.luebking@web.de>
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 WINDOWGEOMETRY_H
#define WINDOWGEOMETRY_H
#include <kwineffects.h>
namespace KWin
{
class WindowGeometry : public QObject, public Effect
{
Q_OBJECT
public:
WindowGeometry();
~WindowGeometry();
inline bool provides( Effect::Feature ef ) { return ef == Effect::GeometryTip; }
void reconfigure( ReconfigureFlags );
void paintScreen(int mask, QRegion region, ScreenPaintData &data);
void windowUserMovedResized( EffectWindow* w, bool first, bool last );
void windowMoveResizeGeometryUpdate( EffectWindow* c, const QRect& geometry );
private slots:
void toggle();
private:
EffectWindow *myResizeWindow;
EffectFrame *myMeasure[3];
QRect myOriginalGeometry, myCurrentGeometry;
bool iAmActive, iAmActivated, iHandleMoves, iHandleResizes;
QString myCoordString[2], myResizeString;
};
} // namespace
#endif

View file

@ -0,0 +1,91 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2010 Thomas Lübking <thomas.luebking@web.de>
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 "windowgeometry_config.h"
#include <kwineffects.h>
#include <KActionCollection>
#include <kaction.h>
#include <klocale.h>
#include <kconfiggroup.h>
namespace KWin
{
KWIN_EFFECT_CONFIG_FACTORY
WindowGeometryConfigForm::WindowGeometryConfigForm(QWidget* parent) : QWidget(parent)
{
setupUi(this);
}
WindowGeometryConfig::WindowGeometryConfig(QWidget* parent, const QVariantList& args)
: KCModule(KWin::EffectFactory::componentData(), parent, args)
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(myUi = new WindowGeometryConfigForm(this));
// Shortcut config. The shortcut belongs to the component "kwin"!
myActionCollection = new KActionCollection( this, KComponentData("kwin") );
KAction* a = (KAction*)myActionCollection->addAction( "WindowGeometry" );
a->setText( i18n("Toggle KWin composited geometry display" ));
a->setProperty("isConfigurationAction", true);
a->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::SHIFT + Qt::Key_F11 ));
myUi->shortcuts->addCollection(myActionCollection);
connect(myUi->shortcuts, SIGNAL(keyChange()), this, SLOT(changed()));
connect(myUi->handleMove, SIGNAL(toggled(bool)), this, SLOT(changed()));
connect(myUi->handleResize, SIGNAL(toggled(bool)), this, SLOT(changed()));
}
WindowGeometryConfig::~WindowGeometryConfig()
{
// Undo (only) unsaved changes to global key shortcuts
myUi->shortcuts->undoChanges();
}
void WindowGeometryConfig::load()
{
KCModule::load();
KConfigGroup conf = EffectsHandler::effectConfig("WindowGeometry");
myUi->handleMove->setChecked( conf.readEntry("Move", true) );
myUi->handleResize->setChecked( conf.readEntry("Resize", true) );
emit changed(false);
}
void WindowGeometryConfig::save()
{
KConfigGroup conf = EffectsHandler::effectConfig("WindowGeometry");
conf.writeEntry("Move", myUi->handleMove->isChecked());
conf.writeEntry("Resize", myUi->handleResize->isChecked());
myUi->shortcuts->save(); // undo() will restore to this state from now on
conf.sync();
emit changed(false);
EffectsHandler::sendReloadMessage( "windowgeometry" );
}
void WindowGeometryConfig::defaults()
{
myUi->handleMove->setChecked( true );
myUi->handleResize->setChecked( true );
myUi->shortcuts->allDefault();
emit changed(true);
}
} //namespace
#include "windowgeometry_config.moc"

View file

@ -0,0 +1,9 @@
[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KCModule
X-KDE-Library=kcm_kwin4_effect_builtins
X-KDE-ParentComponents=kwin4_effect_windowgeometry
X-KDE-PluginKeyword=windowgeometry
Name=WindowGeometry

View file

@ -0,0 +1,58 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2010 Thomas Lübking <thomas.luebking@web.de>
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 WINDOWGEOMETRY_CONFIG_H
#define WINDOWGEOMETRY_CONFIG_H
#include <kcmodule.h>
#include "ui_windowgeometry_config.h"
namespace KWin
{
class WindowGeometryConfigForm : public QWidget, public Ui::WindowGeometryConfigForm
{
Q_OBJECT
public:
explicit WindowGeometryConfigForm(QWidget* parent);
};
class WindowGeometryConfig : public KCModule
{
Q_OBJECT
public:
explicit WindowGeometryConfig(QWidget* parent = 0, const QVariantList& args = QVariantList());
~WindowGeometryConfig();
public slots:
void save();
void load();
void defaults();
private:
WindowGeometryConfigForm* myUi;
KActionCollection* myActionCollection;
};
} // namespace
#endif

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KWin::WindowGeometryConfigForm</class>
<widget class="QWidget" name="KWin::WindowGeometryConfigForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>187</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="handleMove">
<property name="text">
<string>Display for moving windows</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="handleResize">
<property name="text">
<string>Display for resizing windows</string>
</property>
</widget>
</item>
<item>
<widget class="KWin::GlobalShortcutsEditor" name="shortcuts" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KWin::GlobalShortcutsEditor</class>
<extends>QWidget</extends>
<header location="global">kwineffects.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -2695,7 +2695,7 @@ void Client::clearbound()
void Client::doDrawbound( const QRect& geom, bool clear )
{
if( effects && static_cast<EffectsHandlerImpl*>(effects)->providesResizeEffect() )
if( effects && static_cast<EffectsHandlerImpl*>(effects)->provides( Effect::Resize ) )
return; // done by effect
if( decoration != NULL && decoration->drawbound( geom, clear ) )
return; // done by decoration
@ -2727,7 +2727,9 @@ void Client::positionGeometryTip()
{
assert( isMove() || isResize());
// Position and Size display
if (options->showGeometryTip())
if ( effects && static_cast<EffectsHandlerImpl*>(effects)->provides( Effect::GeometryTip ) )
return; // some effect paints this for us
if ( options->showGeometryTip() )
{
if( !geometryTip )
{ // save under is not necessary with opaque, and seem to make things slower
@ -3348,7 +3350,7 @@ void Client::performMoveResize()
bool transparent = false;
if( isResize() )
{
haveResizeEffect = effects && static_cast<EffectsHandlerImpl*>(effects)->providesResizeEffect();
haveResizeEffect = effects && static_cast<EffectsHandlerImpl*>(effects)->provides( Effect::Resize );
transparent = haveResizeEffect || rules()->checkMoveResizeMode( options->resizeMode) != Options::Opaque;
}
else if ( isMove())

View file

@ -1172,6 +1172,8 @@ void KMovingConfig::save( void )
cg.writeEntry(KWM_CNTR_SNAP_ZONE,getCenterSnapZone());
cg.writeEntry("SnapOnlyWhenOverlapping",OverlapSnap->isChecked());
KConfigGroup( config, "Plugins" ).writeEntry("kwin4_effect_windowgeometryEnabled", getGeometryTip());
if (standAlone)
{
config->sync();

View file

@ -251,6 +251,11 @@ void Effect::paintEffectFrame( KWin::EffectFrame* frame, QRegion region, double
{
effects->paintEffectFrame( frame, region, opacity, frameOpacity );
}
bool Effect::provides( Feature )
{
return false;
}
void Effect::drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{

View file

@ -325,6 +325,11 @@ class KWIN_EXPORT Effect
PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS = 1 << 9
};
enum Feature
{
Nothing = 0, Resize, GeometryTip
};
/**
* Constructs new Effect object.
**/
@ -419,7 +424,7 @@ class KWIN_EXPORT Effect
* Called on Transparent resizes.
* return true if your effect substitutes the XOR rubberband
*/
virtual bool isResizeEffect() { return false; }
virtual bool provides( Feature );
/**
* Can be called to draw multiple copies (e.g. thumbnails) of a window.