From 1a3bc3f60cc825c153032f95f90da1dd2e1e8a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 24 Apr 2013 09:50:04 +0200 Subject: [PATCH] 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. --- effects.cpp | 10 --- effects.h | 2 - effects/CMakeLists.txt | 1 - effects/outline/CMakeLists.txt | 12 --- effects/outline/outline.cpp | 86 --------------------- effects/outline/outline.desktop | 114 --------------------------- effects/outline/outline.h | 52 ------------- libkwineffects/kwineffects.h | 16 ---- outline.cpp | 131 +++++++++++++++++++++++++++----- outline.h | 84 +++++++++++++++++--- workspace.cpp | 3 +- 11 files changed, 185 insertions(+), 326 deletions(-) delete mode 100644 effects/outline/CMakeLists.txt delete mode 100644 effects/outline/outline.cpp delete mode 100644 effects/outline/outline.desktop delete mode 100644 effects/outline/outline.h diff --git a/effects.cpp b/effects.cpp index 260d4e4e46..aaf6e18749 100644 --- a/effects.cpp +++ b/effects.cpp @@ -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)) { diff --git a/effects.h b/effects.h index 0cc2e28ecb..2da6a324ee 100644 --- a/effects.h +++ b/effects.h @@ -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); diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt index 62a0720f8e..c580568345 100644 --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -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 ) diff --git a/effects/outline/CMakeLists.txt b/effects/outline/CMakeLists.txt deleted file mode 100644 index 1739f9bf52..0000000000 --- a/effects/outline/CMakeLists.txt +++ /dev/null @@ -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 ) diff --git a/effects/outline/outline.cpp b/effects/outline/outline.cpp deleted file mode 100644 index 97c3735a6b..0000000000 --- a/effects/outline/outline.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2011 Martin Gräßlin - -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 . -*********************************************************************/ - -#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 diff --git a/effects/outline/outline.desktop b/effects/outline/outline.desktop deleted file mode 100644 index bfc0cb4349..0000000000 --- a/effects/outline/outline.desktop +++ /dev/null @@ -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 diff --git a/effects/outline/outline.h b/effects/outline/outline.h deleted file mode 100644 index 5d3df9c62a..0000000000 --- a/effects/outline/outline.h +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2011 Martin Gräßlin - -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 . -*********************************************************************/ - -#ifndef KWIN_OUTLINE_H -#define KWIN_OUTLINE_H - -#include - -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 diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h index f6a8ed6710..a08a99b2ea 100644 --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -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). diff --git a/outline.cpp b/outline.cpp index 978855179c..88835ae113 100644 --- a/outline.cpp +++ b/outline.cpp @@ -21,18 +21,23 @@ along with this program. If not, see . // own #include "outline.h" // KWin -#include "effects.h" +#include "composite.h" // KWin libs #include +// Plasma +#include +// Qt +#include // xcb #include 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(effects)->provides(Effect::Outline)) { - static_cast(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(effects)->provides(Effect::Outline)) { - static_cast(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 diff --git a/outline.h b/outline.h index d34169c730..82e64300aa 100644 --- a/outline.h +++ b/outline.h @@ -23,7 +23,12 @@ along with this program. If not, see . #include "xcbutils.h" #include +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 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 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 inline -void Outline::forEachWindow(T method) +void NonCompositedOutlineVisual::forEachWindow(T method) { (m_topOutline.*method)(); (m_rightOutline.*method)(); diff --git a/workspace.cpp b/workspace.cpp index 687fc593a2..fc94d34ad6 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -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();