Split Outline in a composited and non-composited part

The non-composited part handles the showWithX case with the four small
windows. The composited part shows a translucent QWidget with the
FrameSvg as done by the selection effect frame.

Outline connects to the Compositor toggled signal to switch the mode if
compositing gets suspended/resumed. This works fine also in the case that
the switch happens while the outline is shown. To support this Outline
is now a QObject and created with Workspace as a parent.

Given that the Outline handles both cases by itself, the outline effect
is no longer needed and is dropped together with all the hooks into the
effect system.
icc-effect-5.14.5
Martin Gräßlin 2013-04-24 09:50:04 +02:00
parent 83e3f18014
commit 1a3bc3f60c
11 changed files with 185 additions and 326 deletions

View File

@ -1616,16 +1616,6 @@ QVariant EffectsHandlerImpl::kwinOption(KWinOption kwopt)
}
}
void EffectsHandlerImpl::slotShowOutline(const QRect& geometry)
{
emit showOutline(geometry);
}
void EffectsHandlerImpl::slotHideOutline()
{
emit hideOutline();
}
QString EffectsHandlerImpl::supportInformation(const QString &name) const
{
if (!isEffectLoaded(name)) {

View File

@ -202,8 +202,6 @@ public Q_SLOTS:
void slotCurrentTabAboutToChange(EffectWindow* from, EffectWindow* to);
void slotTabAdded(EffectWindow* from, EffectWindow* to);
void slotTabRemoved(EffectWindow* c, EffectWindow* newActiveWindow);
void slotShowOutline(const QRect &geometry);
void slotHideOutline();
// slots for D-Bus interface
Q_SCRIPTABLE void reconfigureEffect(const QString& name);

View File

@ -111,7 +111,6 @@ endif()
# Common effects
include( dialogparent/CMakeLists.txt )
include( outline/CMakeLists.txt )
include( presentwindows/CMakeLists.txt )
include( screenedge/CMakeLists.txt )
include( slidingpopups/CMakeLists.txt )

View File

@ -1,12 +0,0 @@
#######################################
# Effect
# Source files
set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources}
outline/outline.cpp
)
# .desktop files
install( FILES
outline/outline.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin )

View File

@ -1,86 +0,0 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "outline.h"
namespace KWin
{
KWIN_EFFECT(outline, OutlineEffect)
OutlineEffect::OutlineEffect()
: Effect()
, m_active(false)
, m_outline(NULL)
{
connect(effects, SIGNAL(showOutline(QRect)), SLOT(slotShowOutline(QRect)));
connect(effects, SIGNAL(hideOutline()), SLOT(slotHideOutline()));
}
OutlineEffect::~OutlineEffect()
{
delete m_outline;
}
void OutlineEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
{
effects->paintScreen(mask, region, data);
if (m_active) {
m_outline->render();
}
}
bool OutlineEffect::provides(Feature feature)
{
if (feature == Outline) {
return true;
} else {
return false;
}
}
void OutlineEffect::slotHideOutline()
{
m_active = false;
effects->addRepaint(m_geometry);
}
void OutlineEffect::slotShowOutline(const QRect& geometry)
{
if (m_active) {
effects->addRepaint(m_geometry);
}
m_active = true;
m_geometry = geometry;
if (!m_outline) {
m_outline = effects->effectFrame(EffectFrameNone);
}
m_outline->setGeometry(geometry);
m_outline->setSelection(geometry);
effects->addRepaint(geometry);
}
bool OutlineEffect::isActive() const
{
return m_active;
}
} // namespace

View File

@ -1,114 +0,0 @@
[Desktop Entry]
Name=Outline
Name[bs]=Kontura
Name[ca]=Contorn
Name[ca@valencia]=Contorn
Name[cs]=Obrys
Name[da]=Omrids
Name[de]=Umriss
Name[el]=Περίγραμμα
Name[es]=Contorno
Name[et]=Kontuur
Name[eu]=Zirriborroa
Name[fa]=طرح کلی
Name[fi]=Ääriviiva
Name[fr]=Esquisse
Name[gl]=Contorno
Name[he]=מתאר
Name[hr]=Kontura
Name[hu]=Körvonal
Name[ia]=Profilo
Name[is]=Útlína
Name[it]=Bordo
Name[kk]=Айнала сызық
Name[km]=គ្រោង
Name[ko]=외곽선
Name[lt]=Apibrėžti
Name[lv]=Kontūra
Name[mr]=रूपरेषा
Name[nb]=Omriss
Name[nds]=Ümreet
Name[nl]=Omlijning
Name[pa]=ਆਉਟਲਾਈਨ
Name[pl]=Zarys
Name[pt]=Contorno
Name[pt_BR]=Contorno
Name[ro]=Contur
Name[ru]=Контур окна
Name[sk]=Obrys
Name[sl]=Obris
Name[sr]=Контура
Name[sr@ijekavian]=Контура
Name[sr@ijekavianlatin]=Kontura
Name[sr@latin]=Kontura
Name[sv]=Kontur
Name[tr]=Anahat
Name[ug]=ئىزنا
Name[uk]=Контур
Name[wa]=Cotoû
Name[x-test]=xxOutlinexx
Name[zh_CN]=概要
Name[zh_TW]=輪廓
Icon=preferences-system-windows-effect-outline
Comment=Helper effect to render an outline
Comment[bs]=Pomoćni efekt za crtanje konture
Comment[ca]=Efecte auxiliar per dibuixar un contorn
Comment[ca@valencia]=Efecte auxiliar per dibuixar un contorn
Comment[cs]=Pomocný efekt pro vykreslení obrysu
Comment[da]=Hjælpeeffekt til at rendere et omrids
Comment[de]=Hilfseffekt, der einen Umriss zeichnet.
Comment[el]=Εφέ αποτύπωσης ενός περιγράμματος
Comment[es]=Efecto de ayuda para representar un contorno
Comment[et]=Abiefekt kontuuri renderdamiseks
Comment[eu]=Zirriborro bat errendatzeko efektu laguntzailea
Comment[fi]=Piirtää ikkunoiden ääriviivat
Comment[fr]=Effet d'assistance permettant de dessiner dans un style esquissé
Comment[gl]=Efecto auxiliar para debuxar un contorno
Comment[he]=אפקט שמצייר מתאר
Comment[hr]=Pomoćni efekt za iscrtavanje konture
Comment[hu]=Segédeffektus körvonal rajzolásához
Comment[ia]=Effecto de adjuta pro render un profilo
Comment[is]=Myndgerir útlínu
Comment[it]=Effetto per creare un bordo
Comment[kk]=Айнала сызық салу көмек эффекті
Comment[km]=បែបផែន​កម្មវិធី​​ជំនួយ​ ដើម្បី​បង្ហាញ​គ្រោង
Comment[ko]=창 외곽선 도우미 효과
Comment[lt]=Pagalbos efektas vaizduoti kontūrą
Comment[lv]=Palīgefekts kontūras zīmēšanai
Comment[mr]=रूपरेषा आखण्यासाठी हा मदत परिणाम वापरा
Comment[nb]=Hjelper-effekt for å tegne et omriss
Comment[nds]=Hölper för't Opstellen vun en Ümreet
Comment[nl]=Effect van hulp bij weergeven van omlijning
Comment[pl]=Efekt pomocniczy przy renderowania zarysu
Comment[pt]=Efeito auxiliar para desenhar um contorno
Comment[pt_BR]=Efeito auxiliar para desenhar um contorno
Comment[ro]=Efect ajutător pentru desenarea unui contur
Comment[ru]=Вспомогательный эффект для отрисовки контуров окон
Comment[sk]=Pomocný efekt na vykreslenie obrysu
Comment[sl]=Pomožni učinek, ki izrisuje obris
Comment[sr]=Помоћни ефекат за исцртавање контуре
Comment[sr@ijekavian]=Помоћни ефекат за исцртавање контуре
Comment[sr@ijekavianlatin]=Pomoćni efekat za iscrtavanje konture
Comment[sr@latin]=Pomoćni efekat za iscrtavanje konture
Comment[sv]=Hjälpeffekt för att återge en kontur
Comment[tr]=Anahattı render etmek için yardımcı efekt
Comment[ug]=ئىزناسىنى سىزىدىغان ياردەمچىنىڭ ئۈنۈمى
Comment[uk]=Допоміжний ефект показу контуру
Comment[vi]=Hiệu ứng trợ giúp để hiển thị viền cửa sổ
Comment[wa]=Efet aidant pol rindou d' on cotoû
Comment[x-test]=xxHelper effect to render an outlinexx
Comment[zh_CN]=渲染概览的辅助效果
Comment[zh_TW]=繪製輪廓的效果
Type=Service
X-KDE-ServiceTypes=KWin/Effect
X-KDE-PluginInfo-Author=Martin Gräßlin
X-KDE-PluginInfo-Email=mgraesslin@kde.org
X-KDE-PluginInfo-Name=kwin4_effect_outline
X-KDE-PluginInfo-Version=0.1.0
X-KDE-PluginInfo-Category=Window Management
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-Library=kwin4_effect_builtins
X-KDE-Ordering=90

View File

@ -1,52 +0,0 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_OUTLINE_H
#define KWIN_OUTLINE_H
#include <kwineffects.h>
namespace KWin
{
class OutlineEffect : public Effect
{
Q_OBJECT
public:
OutlineEffect();
virtual ~OutlineEffect();
virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data);
virtual bool provides(Feature feature);
virtual bool isActive() const;
public Q_SLOTS:
void slotShowOutline(const QRect &geometry);
void slotHideOutline();
private:
QRect m_geometry;
bool m_active;
EffectFrame *m_outline;
};
} // namespace
#endif // KWIN_OUTLINE_H

View File

@ -1135,22 +1135,6 @@ Q_SIGNALS:
* @since 4.7
*/
void propertyNotify(KWin::EffectWindow* w, long atom);
/**
* Requests to show an outline. An effect providing to show an outline should
* connect to the signal and render an outline.
* The outline should be shown till the signal is emitted again with a new
* geometry or the @link hideOutline signal is emitted.
* @param outline The geometry of the outline to render.
* @see hideOutline
* @since 4.7
**/
void showOutline(const QRect& outline);
/**
* Signal emitted when the outline should no longer be shown.
* @see showOutline
* @since 4.7
**/
void hideOutline();
/**
* Signal emitted after the screen geometry changed (e.g. add of a monitor).

View File

@ -21,18 +21,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// own
#include "outline.h"
// KWin
#include "effects.h"
#include "composite.h"
// KWin libs
#include <kwinxrenderutils.h>
// Plasma
#include <Plasma/FrameSvg>
// Qt
#include <QPainter>
// xcb
#include <xcb/render.h>
namespace KWin {
Outline::Outline()
: m_initialized(false)
Outline::Outline(QObject *parent)
: QObject(parent)
, m_active(false)
{
connect(Compositor::self(), SIGNAL(compositingToggled(bool)), SLOT(compositingChanged()));
}
Outline::~Outline()
@ -42,11 +47,14 @@ Outline::~Outline()
void Outline::show()
{
m_active = true;
if (effects && static_cast<EffectsHandlerImpl*>(effects)->provides(Effect::Outline)) {
static_cast<EffectsHandlerImpl*>(effects)->slotShowOutline(m_outlineGeometry);
return; // done by effect
if (m_visual.isNull()) {
createHelper();
}
showWithX();
if (m_visual.isNull()) {
// something went wrong
return;
}
m_visual->show();
}
void Outline::hide()
@ -55,11 +63,10 @@ void Outline::hide()
return;
}
m_active = false;
if (effects && static_cast<EffectsHandlerImpl*>(effects)->provides(Effect::Outline)) {
static_cast<EffectsHandlerImpl*>(effects)->slotHideOutline();
return; // done by effect
if (m_visual.isNull()) {
return;
}
forEachWindow(&Xcb::Window::unmap);
m_visual->hide();
}
void Outline::show(const QRect& outlineGeometry)
@ -73,7 +80,85 @@ void Outline::setGeometry(const QRect& outlineGeometry)
m_outlineGeometry = outlineGeometry;
}
void Outline::showWithX()
void Outline::createHelper()
{
if (!m_visual.isNull()) {
return;
}
if (Compositor::compositing()) {
m_visual.reset(new CompositedOutlineVisual(this));
} else {
m_visual.reset(new NonCompositedOutlineVisual(this));
}
}
void Outline::compositingChanged()
{
m_visual.reset();
if (m_active) {
show();
}
}
OutlineVisual::OutlineVisual(Outline *outline)
: m_outline(outline)
{
}
OutlineVisual::~OutlineVisual()
{
}
CompositedOutlineVisual::CompositedOutlineVisual(Outline *outline)
: QWidget(NULL, Qt::X11BypassWindowManagerHint)
, OutlineVisual(outline)
, m_background(new Plasma::FrameSvg(this))
{
setAttribute(Qt::WA_TranslucentBackground);
QPalette pal = palette();
pal.setColor(backgroundRole(), Qt::transparent);
setPalette(pal);
m_background->setImagePath("widgets/viewitem");
m_background->setElementPrefix("hover");
m_background->setCacheAllRenderedFrames(true);
m_background->setEnabledBorders(Plasma::FrameSvg::AllBorders);
}
CompositedOutlineVisual::~CompositedOutlineVisual()
{
}
void CompositedOutlineVisual::hide()
{
QWidget::hide();
}
void CompositedOutlineVisual::show()
{
const QRect &outlineGeometry = outline()->geometry();
m_background->resizeFrame(outlineGeometry.size());
setGeometry(outlineGeometry);
QWidget::show();
}
void CompositedOutlineVisual::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
m_background->paintFrame(&painter);
}
NonCompositedOutlineVisual::NonCompositedOutlineVisual(Outline *outline)
: OutlineVisual(outline)
, m_initialized(false)
{
}
NonCompositedOutlineVisual::~NonCompositedOutlineVisual()
{
}
void NonCompositedOutlineVisual::show()
{
if (!m_initialized) {
const QRect geo(0, 0, 1, 1);
@ -88,15 +173,16 @@ void Outline::showWithX()
const int defaultDepth = Xcb::defaultDepth();
// left/right parts are between top/bottom, they don't reach as far as the corners
const QRect &outlineGeometry = outline()->geometry();
// left/right parts are between top/bottom, they don't reach as far as the corners
const uint16_t verticalWidth = 5;
const uint16_t verticalHeight = m_outlineGeometry.height() - 10;
const uint16_t horizontalWidth = m_outlineGeometry.width();
const uint16_t verticalHeight = outlineGeometry.height() - 10;
const uint16_t horizontalWidth = outlineGeometry.width();
const uint horizontalHeight = 5;
m_leftOutline.setGeometry(m_outlineGeometry.x(), m_outlineGeometry.y() + 5, verticalWidth, verticalHeight);
m_rightOutline.setGeometry(m_outlineGeometry.x() + m_outlineGeometry.width() - 5, m_outlineGeometry.y() + 5, verticalWidth, verticalHeight);
m_topOutline.setGeometry(m_outlineGeometry.x(), m_outlineGeometry.y(), horizontalWidth, horizontalHeight);
m_bottomOutline.setGeometry(m_outlineGeometry.x(), m_outlineGeometry.y() + m_outlineGeometry.height() - 5, horizontalWidth, horizontalHeight);
m_leftOutline.setGeometry(outlineGeometry.x(), outlineGeometry.y() + 5, verticalWidth, verticalHeight);
m_rightOutline.setGeometry(outlineGeometry.x() + outlineGeometry.width() - 5, outlineGeometry.y() + 5, verticalWidth, verticalHeight);
m_topOutline.setGeometry(outlineGeometry.x(), outlineGeometry.y(), horizontalWidth, horizontalHeight);
m_bottomOutline.setGeometry(outlineGeometry.x(), outlineGeometry.y() + outlineGeometry.height() - 5, horizontalWidth, horizontalHeight);
const xcb_render_color_t white = {0xffff, 0xffff, 0xffff, 0xffff};
QColor qGray(Qt::gray);
@ -151,7 +237,7 @@ void Outline::showWithX()
}
{
xcb_pixmap_t xpix = xcb_generate_id(connection());
xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), m_outlineGeometry.width(), 5);
xcb_create_pixmap(connection(), defaultDepth, xpix, rootWindow(), outlineGeometry.width(), 5);
XRenderPicture pic(xpix, defaultDepth);
xcb_rectangle_t rect = {0, 0, horizontalWidth, horizontalHeight};
@ -176,4 +262,9 @@ void Outline::showWithX()
forEachWindow(&Xcb::Window::map);
}
void NonCompositedOutlineVisual::hide()
{
forEachWindow(&Xcb::Window::unmap);
}
} // namespace

View File

@ -23,7 +23,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "xcbutils.h"
#include <QRect>
namespace Plasma {
class FrameSvg;
}
namespace KWin {
class OutlineVisual;
/**
* @short This class is used to show the outline of a given geometry.
@ -36,9 +41,10 @@ namespace KWin {
* @author Arthur Arlt
* @since 4.7
*/
class Outline {
class Outline : public QObject {
Q_OBJECT
public:
Outline();
Outline(QObject *parent);
~Outline();
/**
@ -71,29 +77,85 @@ public:
*/
void hide();
const QRect &geometry() const;
private Q_SLOTS:
void compositingChanged();
private:
void createHelper();
QScopedPointer<OutlineVisual> m_visual;
QRect m_outlineGeometry;
bool m_active;
};
/**
* Show the window outline using the X implementation
*/
void showWithX();
class OutlineVisual
{
public:
OutlineVisual(Outline *outline);
virtual ~OutlineVisual();
virtual void show() = 0;
virtual void hide() = 0;
protected:
Outline *outline();
const Outline *outline() const;
private:
Outline *m_outline;
};
class CompositedOutlineVisual : public QWidget, public OutlineVisual
{
public:
CompositedOutlineVisual(Outline *outline);
virtual ~CompositedOutlineVisual();
virtual void show();
virtual void hide();
protected:
virtual void paintEvent(QPaintEvent *);
private:
Plasma::FrameSvg *m_background;
};
class NonCompositedOutlineVisual : public OutlineVisual
{
public:
NonCompositedOutlineVisual(Outline *outline);
virtual ~NonCompositedOutlineVisual();
virtual void show();
virtual void hide();
private:
// TODO: variadic template arguments for adding method arguments
template <typename T>
void forEachWindow(T method);
bool m_initialized;
Xcb::Window m_topOutline;
Xcb::Window m_rightOutline;
Xcb::Window m_bottomOutline;
Xcb::Window m_leftOutline;
QRect m_outlineGeometry;
bool m_initialized;
bool m_active;
};
inline
const QRect &Outline::geometry() const
{
return m_outlineGeometry;
}
inline
Outline *OutlineVisual::outline()
{
return m_outline;
}
inline
const Outline *OutlineVisual::outline() const
{
return m_outline;
}
template <typename T>
inline
void Outline::forEachWindow(T method)
void NonCompositedOutlineVisual::forEachWindow(T method)
{
(m_topOutline.*method)();
(m_rightOutline.*method)();

View File

@ -231,7 +231,7 @@ Workspace::Workspace(bool restore)
client_keys = new KActionCollection(this);
m_outline = new Outline();
m_outline = new Outline(this);
initShortcuts();
@ -523,7 +523,6 @@ Workspace::~Workspace()
}
for (UnmanagedList::iterator it = unmanaged.begin(), end = unmanaged.end(); it != end; ++it)
(*it)->release(true);
delete m_outline;
XDeleteProperty(display(), rootWindow(), atoms->kwin_running);
writeWindowRules();