2007-11-27 22:40:25 +03:00
|
|
|
/********************************************************************
|
2007-04-29 21:35:43 +04:00
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
|
|
|
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
|
2011-03-16 21:39:10 +03:00
|
|
|
Copyright (C) 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2007-11-27 22:40:25 +03:00
|
|
|
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/>.
|
|
|
|
*********************************************************************/
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
#include "effects.h"
|
|
|
|
|
2012-08-30 10:20:26 +04:00
|
|
|
#include "effectsadaptor.h"
|
2013-04-04 18:14:12 +04:00
|
|
|
#ifdef KWIN_BUILD_ACTIVITIES
|
|
|
|
#include "activities.h"
|
|
|
|
#endif
|
2013-04-08 14:31:16 +04:00
|
|
|
#include "decorations.h"
|
2007-04-29 21:35:43 +04:00
|
|
|
#include "deleted.h"
|
|
|
|
#include "client.h"
|
2013-02-19 14:25:46 +04:00
|
|
|
#include "cursor.h"
|
2007-04-29 21:35:43 +04:00
|
|
|
#include "group.h"
|
|
|
|
#include "scene_xrender.h"
|
|
|
|
#include "scene_opengl.h"
|
2008-01-02 18:37:46 +03:00
|
|
|
#include "unmanaged.h"
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2011-03-06 14:15:16 +03:00
|
|
|
#include "tabbox.h"
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2013-01-21 12:04:06 +04:00
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
|
|
|
#include "screenedge.h"
|
|
|
|
#endif
|
2012-09-23 09:23:41 +04:00
|
|
|
#ifdef KWIN_BUILD_SCRIPTING
|
2012-01-29 20:32:56 +04:00
|
|
|
#include "scripting/scriptedeffect.h"
|
2012-09-23 09:23:41 +04:00
|
|
|
#endif
|
2013-04-03 14:19:27 +04:00
|
|
|
#include "screens.h"
|
2011-11-10 17:28:06 +04:00
|
|
|
#include "thumbnailitem.h"
|
2012-11-16 11:23:47 +04:00
|
|
|
#include "virtualdesktops.h"
|
2007-04-29 21:35:43 +04:00
|
|
|
#include "workspace.h"
|
|
|
|
#include "kwinglutils.h"
|
|
|
|
|
2013-09-02 15:14:39 +04:00
|
|
|
#include <QDebug>
|
2007-04-29 21:35:43 +04:00
|
|
|
#include <QFile>
|
2013-02-26 12:00:51 +04:00
|
|
|
#include <QFutureWatcher>
|
|
|
|
#include <QtConcurrentRun>
|
2013-01-30 16:07:59 +04:00
|
|
|
#include <QDBusServiceWatcher>
|
|
|
|
#include <QDBusPendingCallWatcher>
|
2013-08-09 16:19:09 +04:00
|
|
|
#include <QStandardPaths>
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-03-07 16:34:40 +04:00
|
|
|
#include <KDE/KLibrary>
|
|
|
|
#include <KDE/KDesktopFile>
|
|
|
|
#include <KDE/KConfigGroup>
|
|
|
|
#include <KDE/KService>
|
|
|
|
#include <KDE/KServiceTypeTrader>
|
|
|
|
#include <KDE/KPluginInfo>
|
2011-02-17 21:35:08 +03:00
|
|
|
#include <Plasma/Theme>
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
#include <assert.h>
|
2011-08-21 23:50:23 +04:00
|
|
|
#include "composite.h"
|
2012-12-20 17:03:02 +04:00
|
|
|
#include "xcbutils.h"
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-01-30 16:07:59 +04:00
|
|
|
// dbus generated
|
|
|
|
#include "screenlocker_interface.h"
|
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
static const QString SCREEN_LOCKER_SERVICE_NAME = QStringLiteral("org.freedesktop.ScreenSaver");
|
2013-01-30 16:07:59 +04:00
|
|
|
|
|
|
|
ScreenLockerWatcher::ScreenLockerWatcher(QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, m_interface(NULL)
|
|
|
|
, m_serviceWatcher(new QDBusServiceWatcher(this))
|
|
|
|
, m_locked(false)
|
|
|
|
{
|
|
|
|
connect(m_serviceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), SLOT(serviceOwnerChanged(QString,QString,QString)));
|
|
|
|
m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
|
|
|
|
m_serviceWatcher->addWatchedService(SCREEN_LOCKER_SERVICE_NAME);
|
|
|
|
// check whether service is registered
|
|
|
|
QFutureWatcher<QDBusReply<bool> > *watcher = new QFutureWatcher<QDBusReply<bool> >(this);
|
|
|
|
connect(watcher, SIGNAL(finished()), SLOT(serviceRegisteredQueried()));
|
|
|
|
connect(watcher, SIGNAL(canceled()), watcher, SLOT(deleteLater()));
|
|
|
|
watcher->setFuture(QtConcurrent::run(QDBusConnection::sessionBus().interface(),
|
|
|
|
&QDBusConnectionInterface::isServiceRegistered,
|
|
|
|
SCREEN_LOCKER_SERVICE_NAME));
|
|
|
|
}
|
|
|
|
|
|
|
|
ScreenLockerWatcher::~ScreenLockerWatcher()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenLockerWatcher::serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
|
|
|
|
{
|
|
|
|
Q_UNUSED(oldOwner)
|
|
|
|
if (serviceName != SCREEN_LOCKER_SERVICE_NAME) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
delete m_interface;
|
|
|
|
m_interface = NULL;
|
|
|
|
m_locked = false;
|
|
|
|
if (!newOwner.isEmpty()) {
|
|
|
|
m_interface = new OrgFreedesktopScreenSaverInterface(newOwner, QString(), QDBusConnection::sessionBus(), this);
|
|
|
|
connect(m_interface, SIGNAL(ActiveChanged(bool)), SLOT(setLocked(bool)));
|
|
|
|
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(m_interface->GetActive(), this);
|
|
|
|
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), SLOT(activeQueried(QDBusPendingCallWatcher*)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenLockerWatcher::serviceRegisteredQueried()
|
|
|
|
{
|
|
|
|
QFutureWatcher<QDBusReply<bool> > *watcher = dynamic_cast<QFutureWatcher<QDBusReply<bool> > *>(sender());
|
|
|
|
if (!watcher) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const QDBusReply<bool> &reply = watcher->result();
|
|
|
|
if (reply.isValid() && reply.value()) {
|
|
|
|
QFutureWatcher<QDBusReply<QString> > *ownerWatcher = new QFutureWatcher<QDBusReply<QString> >(this);
|
|
|
|
connect(ownerWatcher, SIGNAL(finished()), SLOT(serviceOwnerQueried()));
|
|
|
|
connect(ownerWatcher, SIGNAL(canceled()), ownerWatcher, SLOT(deleteLater()));
|
|
|
|
ownerWatcher->setFuture(QtConcurrent::run(QDBusConnection::sessionBus().interface(),
|
|
|
|
&QDBusConnectionInterface::serviceOwner,
|
|
|
|
SCREEN_LOCKER_SERVICE_NAME));
|
|
|
|
}
|
|
|
|
watcher->deleteLater();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenLockerWatcher::serviceOwnerQueried()
|
|
|
|
{
|
|
|
|
QFutureWatcher<QDBusReply<QString> > *watcher = dynamic_cast<QFutureWatcher<QDBusReply<QString> > *>(sender());
|
|
|
|
if (!watcher) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const QDBusReply<QString> reply = watcher->result();
|
|
|
|
if (reply.isValid()) {
|
|
|
|
serviceOwnerChanged(SCREEN_LOCKER_SERVICE_NAME, QString(), reply.value());
|
|
|
|
}
|
|
|
|
|
|
|
|
watcher->deleteLater();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenLockerWatcher::activeQueried(QDBusPendingCallWatcher *watcher)
|
|
|
|
{
|
|
|
|
QDBusPendingReply<bool> reply = *watcher;
|
|
|
|
if (!reply.isError()) {
|
|
|
|
setLocked(reply.value());
|
|
|
|
}
|
|
|
|
watcher->deleteLater();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenLockerWatcher::setLocked(bool activated)
|
|
|
|
{
|
|
|
|
if (m_locked == activated) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_locked = activated;
|
|
|
|
emit locked(m_locked);
|
|
|
|
}
|
|
|
|
|
2010-02-01 10:44:27 +03:00
|
|
|
//---------------------
|
|
|
|
// Static
|
|
|
|
|
2013-09-11 10:38:10 +04:00
|
|
|
static QByteArray readWindowProperty(xcb_window_t win, xcb_atom_t atom, xcb_atom_t type, int format)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-09-11 10:38:10 +04:00
|
|
|
uint32_t len = 32768;
|
|
|
|
xcb_connection_t *c = connection();
|
2011-01-30 17:34:42 +03:00
|
|
|
for (;;) {
|
2013-09-11 10:38:10 +04:00
|
|
|
const auto cookie = xcb_get_property_unchecked(c, false, win, atom, XCB_ATOM_ANY, 0, len);
|
|
|
|
ScopedCPointer<xcb_get_property_reply_t> prop(xcb_get_property_reply(c, cookie, nullptr));
|
|
|
|
if (prop.isNull()) {
|
|
|
|
// get property failed
|
2010-02-01 10:44:27 +03:00
|
|
|
return QByteArray();
|
2013-09-11 10:38:10 +04:00
|
|
|
}
|
|
|
|
if (prop->bytes_after > 0) {
|
|
|
|
len *= 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (prop->type == type && prop->format == format) {
|
2013-09-25 10:54:22 +04:00
|
|
|
return QByteArray(reinterpret_cast< const char* >(xcb_get_property_value(prop.data())),
|
|
|
|
xcb_get_property_value_length(prop.data()));
|
2013-09-11 10:38:10 +04:00
|
|
|
} else {
|
|
|
|
return QByteArray();
|
|
|
|
}
|
2010-02-01 10:44:27 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-02-01 10:44:27 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
static void deleteWindowProperty(Window win, long int atom)
|
|
|
|
{
|
2013-09-10 11:33:07 +04:00
|
|
|
xcb_delete_property(connection(), win, atom);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-02-01 10:44:27 +03:00
|
|
|
|
|
|
|
//---------------------
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2012-08-23 20:04:36 +04:00
|
|
|
EffectsHandlerImpl::EffectsHandlerImpl(Compositor *compositor, Scene *scene)
|
2012-08-16 23:19:54 +04:00
|
|
|
: EffectsHandler(scene->compositingType())
|
2011-01-30 17:34:42 +03:00
|
|
|
, keyboard_grab_effect(NULL)
|
|
|
|
, fullscreen_effect(0)
|
|
|
|
, next_window_quad_type(EFFECT_QUAD_TYPE_START)
|
2012-08-23 20:04:36 +04:00
|
|
|
, m_compositor(compositor)
|
2012-08-16 23:19:54 +04:00
|
|
|
, m_scene(scene)
|
2013-01-30 16:07:59 +04:00
|
|
|
, m_screenLockerWatcher(new ScreenLockerWatcher(this))
|
2012-03-29 22:12:34 +04:00
|
|
|
, m_desktopRendering(false)
|
|
|
|
, m_currentRenderedDesktop(0)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-08-30 10:20:26 +04:00
|
|
|
new EffectsAdaptor(this);
|
|
|
|
QDBusConnection dbus = QDBusConnection::sessionBus();
|
2013-07-23 09:02:52 +04:00
|
|
|
dbus.registerObject(QStringLiteral("/Effects"), this);
|
|
|
|
dbus.registerService(QStringLiteral("org.kde.kwin.Effects"));
|
2011-11-27 21:36:59 +04:00
|
|
|
// init is important, otherwise causes crashes when quads are build before the first painting pass start
|
2013-07-19 13:34:01 +04:00
|
|
|
m_currentBuildQuadsIterator = m_activeEffects.constEnd();
|
2011-11-27 21:36:59 +04:00
|
|
|
|
2011-02-25 22:41:10 +03:00
|
|
|
Workspace *ws = Workspace::self();
|
2012-11-16 11:23:47 +04:00
|
|
|
VirtualDesktopManager *vds = VirtualDesktopManager::self();
|
2013-05-11 16:09:15 +04:00
|
|
|
connect(ws, SIGNAL(currentDesktopChanged(int,KWin::Client*)), SLOT(slotDesktopChanged(int,KWin::Client*)));
|
2011-02-26 00:06:02 +03:00
|
|
|
connect(ws, SIGNAL(clientAdded(KWin::Client*)), this, SLOT(slotClientAdded(KWin::Client*)));
|
|
|
|
connect(ws, SIGNAL(unmanagedAdded(KWin::Unmanaged*)), this, SLOT(slotUnmanagedAdded(KWin::Unmanaged*)));
|
2011-02-27 12:05:04 +03:00
|
|
|
connect(ws, SIGNAL(clientActivated(KWin::Client*)), this, SLOT(slotClientActivated(KWin::Client*)));
|
2011-02-27 12:47:42 +03:00
|
|
|
connect(ws, SIGNAL(deletedRemoved(KWin::Deleted*)), this, SLOT(slotDeletedRemoved(KWin::Deleted*)));
|
2012-11-16 11:23:47 +04:00
|
|
|
connect(vds, SIGNAL(countChanged(uint,uint)), SIGNAL(numberDesktopsChanged(uint)));
|
2013-02-19 14:25:46 +04:00
|
|
|
connect(Cursor::self(), SIGNAL(mouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)),
|
2011-03-12 16:37:30 +03:00
|
|
|
SIGNAL(mouseChanged(QPoint,QPoint,Qt::MouseButtons,Qt::MouseButtons,Qt::KeyboardModifiers,Qt::KeyboardModifiers)));
|
2011-03-12 21:18:19 +03:00
|
|
|
connect(ws, SIGNAL(propertyNotify(long)), this, SLOT(slotPropertyNotify(long)));
|
2013-04-04 18:14:12 +04:00
|
|
|
#ifdef KWIN_BUILD_ACTIVITIES
|
|
|
|
Activities *activities = Activities::self();
|
|
|
|
connect(activities, SIGNAL(added(QString)), SIGNAL(activityAdded(QString)));
|
|
|
|
connect(activities, SIGNAL(removed(QString)), SIGNAL(activityRemoved(QString)));
|
|
|
|
connect(activities, SIGNAL(currentChanged(QString)), SIGNAL(currentActivityChanged(QString)));
|
|
|
|
#endif
|
2013-01-01 04:47:16 +04:00
|
|
|
connect(ws, SIGNAL(stackingOrderChanged()), SIGNAL(stackingOrderChanged()));
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
TabBox::TabBox *tabBox = TabBox::TabBox::self();
|
|
|
|
connect(tabBox, SIGNAL(tabBoxAdded(int)), SIGNAL(tabBoxAdded(int)));
|
|
|
|
connect(tabBox, SIGNAL(tabBoxUpdated()), SIGNAL(tabBoxUpdated()));
|
|
|
|
connect(tabBox, SIGNAL(tabBoxClosed()), SIGNAL(tabBoxClosed()));
|
|
|
|
connect(tabBox, SIGNAL(tabBoxKeyEvent(QKeyEvent*)), SIGNAL(tabBoxKeyEvent(QKeyEvent*)));
|
2013-01-26 14:50:14 +04:00
|
|
|
#endif
|
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
|
|
|
connect(ScreenEdges::self(), SIGNAL(approaching(ElectricBorder,qreal,QRect)), SIGNAL(screenEdgeApproaching(ElectricBorder,qreal,QRect)));
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2013-01-30 16:07:59 +04:00
|
|
|
connect(m_screenLockerWatcher, SIGNAL(locked(bool)), SIGNAL(screenLockingChanged(bool)));
|
2011-02-27 11:25:45 +03:00
|
|
|
// connect all clients
|
2013-09-24 16:31:35 +04:00
|
|
|
for (Client *c : ws->clientList()) {
|
2011-03-06 13:13:11 +03:00
|
|
|
setupClientConnections(c);
|
2011-02-27 11:25:45 +03:00
|
|
|
}
|
2013-09-24 16:31:35 +04:00
|
|
|
for (Unmanaged *u : ws->unmanagedList()) {
|
2011-03-06 13:13:11 +03:00
|
|
|
setupUnmanagedConnections(u);
|
2011-02-27 11:25:45 +03:00
|
|
|
}
|
2007-05-28 15:23:00 +04:00
|
|
|
reconfigure();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
EffectsHandlerImpl::~EffectsHandlerImpl()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (keyboard_grab_effect != NULL)
|
2007-04-29 21:35:43 +04:00
|
|
|
ungrabKeyboard();
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const EffectPair & ep : loaded_effects)
|
|
|
|
unloadEffect(ep.first);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-03-06 13:13:11 +03:00
|
|
|
void EffectsHandlerImpl::setupClientConnections(Client* c)
|
|
|
|
{
|
2011-06-21 15:52:25 +04:00
|
|
|
connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), this, SLOT(slotWindowClosed(KWin::Toplevel*)));
|
2011-03-06 13:13:11 +03:00
|
|
|
connect(c, SIGNAL(clientMaximizedStateChanged(KWin::Client*,KDecorationDefines::MaximizeMode)), this, SLOT(slotClientMaximized(KWin::Client*,KDecorationDefines::MaximizeMode)));
|
2011-03-13 14:41:30 +03:00
|
|
|
connect(c, SIGNAL(clientStartUserMovedResized(KWin::Client*)), this, SLOT(slotClientStartUserMovedResized(KWin::Client*)));
|
|
|
|
connect(c, SIGNAL(clientStepUserMovedResized(KWin::Client*,QRect)), this, SLOT(slotClientStepUserMovedResized(KWin::Client*,QRect)));
|
|
|
|
connect(c, SIGNAL(clientFinishUserMovedResized(KWin::Client*)), this, SLOT(slotClientFinishUserMovedResized(KWin::Client*)));
|
2011-03-06 13:13:11 +03:00
|
|
|
connect(c, SIGNAL(opacityChanged(KWin::Toplevel*,qreal)), this, SLOT(slotOpacityChanged(KWin::Toplevel*,qreal)));
|
|
|
|
connect(c, SIGNAL(clientMinimized(KWin::Client*,bool)), this, SLOT(slotClientMinimized(KWin::Client*,bool)));
|
|
|
|
connect(c, SIGNAL(clientUnminimized(KWin::Client*,bool)), this, SLOT(slotClientUnminimized(KWin::Client*,bool)));
|
2013-06-19 18:26:55 +04:00
|
|
|
connect(c, SIGNAL(modalChanged()), this, SLOT(slotClientModalityChanged()));
|
2011-06-20 00:07:19 +04:00
|
|
|
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), this, SLOT(slotGeometryShapeChanged(KWin::Toplevel*,QRect)));
|
2012-03-25 01:42:29 +04:00
|
|
|
connect(c, SIGNAL(paddingChanged(KWin::Toplevel*,QRect)), this, SLOT(slotPaddingChanged(KWin::Toplevel*,QRect)));
|
2011-03-12 17:04:22 +03:00
|
|
|
connect(c, SIGNAL(damaged(KWin::Toplevel*,QRect)), this, SLOT(slotWindowDamaged(KWin::Toplevel*,QRect)));
|
2011-03-12 21:18:19 +03:00
|
|
|
connect(c, SIGNAL(propertyNotify(KWin::Toplevel*,long)), this, SLOT(slotPropertyNotify(KWin::Toplevel*,long)));
|
2011-03-06 13:13:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectsHandlerImpl::setupUnmanagedConnections(Unmanaged* u)
|
|
|
|
{
|
2011-06-21 15:52:25 +04:00
|
|
|
connect(u, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), this, SLOT(slotWindowClosed(KWin::Toplevel*)));
|
2011-03-06 13:13:11 +03:00
|
|
|
connect(u, SIGNAL(opacityChanged(KWin::Toplevel*,qreal)), this, SLOT(slotOpacityChanged(KWin::Toplevel*,qreal)));
|
2011-06-20 00:07:19 +04:00
|
|
|
connect(u, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), this, SLOT(slotGeometryShapeChanged(KWin::Toplevel*,QRect)));
|
2012-03-25 01:42:29 +04:00
|
|
|
connect(u, SIGNAL(paddingChanged(KWin::Toplevel*,QRect)), this, SLOT(slotPaddingChanged(KWin::Toplevel*,QRect)));
|
2011-03-12 17:04:22 +03:00
|
|
|
connect(u, SIGNAL(damaged(KWin::Toplevel*,QRect)), this, SLOT(slotWindowDamaged(KWin::Toplevel*,QRect)));
|
2011-03-12 21:18:19 +03:00
|
|
|
connect(u, SIGNAL(propertyNotify(KWin::Toplevel*,long)), this, SLOT(slotPropertyNotify(KWin::Toplevel*,long)));
|
2011-03-06 13:13:11 +03:00
|
|
|
}
|
|
|
|
|
2007-05-28 15:23:00 +04:00
|
|
|
void EffectsHandlerImpl::reconfigure()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-04-13 13:36:48 +04:00
|
|
|
// perform querying for the services in a thread
|
|
|
|
QFutureWatcher<KService::List> *watcher = new QFutureWatcher<KService::List>(this);
|
|
|
|
connect(watcher, SIGNAL(finished()), this, SLOT(slotEffectsQueried()));
|
2013-07-23 09:02:52 +04:00
|
|
|
watcher->setFuture(QtConcurrent::run(KServiceTypeTrader::self(), &KServiceTypeTrader::query, QStringLiteral("KWin/Effect"), QString()));
|
2012-04-13 13:36:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectsHandlerImpl::slotEffectsQueried()
|
|
|
|
{
|
|
|
|
QFutureWatcher<KService::List> *watcher = dynamic_cast< QFutureWatcher<KService::List>* >(sender());
|
|
|
|
if (!watcher) {
|
|
|
|
// slot invoked not from a FutureWatcher
|
|
|
|
return;
|
|
|
|
}
|
2007-05-28 15:23:00 +04:00
|
|
|
|
2012-04-13 13:36:48 +04:00
|
|
|
KService::List offers = watcher->result();
|
2007-07-21 22:30:06 +04:00
|
|
|
QStringList effectsToBeLoaded;
|
2011-05-02 00:37:59 +04:00
|
|
|
QStringList checkDefault;
|
2013-09-04 18:10:36 +04:00
|
|
|
KConfigGroup conf(KSharedConfig::openConfig(), "Plugins");
|
2011-05-02 00:37:59 +04:00
|
|
|
|
2007-07-21 22:30:06 +04:00
|
|
|
// First unload necessary effects
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const KService::Ptr & service : offers) {
|
2011-01-30 17:34:42 +03:00
|
|
|
KPluginInfo plugininfo(service);
|
|
|
|
plugininfo.load(conf);
|
2007-05-28 15:23:00 +04:00
|
|
|
|
2011-05-02 00:37:59 +04:00
|
|
|
if (plugininfo.isPluginEnabledByDefault()) {
|
|
|
|
const QString key = plugininfo.pluginName() + QString::fromLatin1("Enabled");
|
|
|
|
if (!conf.hasKey(key))
|
|
|
|
checkDefault.append(plugininfo.pluginName());
|
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
bool isloaded = isEffectLoaded(plugininfo.pluginName());
|
2007-05-29 15:42:47 +04:00
|
|
|
bool shouldbeloaded = plugininfo.isPluginEnabled();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!shouldbeloaded && isloaded)
|
|
|
|
unloadEffect(plugininfo.pluginName());
|
|
|
|
if (shouldbeloaded)
|
|
|
|
effectsToBeLoaded.append(plugininfo.pluginName());
|
|
|
|
}
|
2008-10-02 13:27:32 +04:00
|
|
|
QStringList newLoaded;
|
2007-07-21 22:30:06 +04:00
|
|
|
// Then load those that should be loaded
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const QString & effectName : effectsToBeLoaded) {
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!isEffectLoaded(effectName)) {
|
2011-05-02 00:37:59 +04:00
|
|
|
if (loadEffect(effectName, checkDefault.contains(effectName)))
|
|
|
|
newLoaded.append(effectName);
|
2008-10-02 13:27:32 +04:00
|
|
|
}
|
2007-05-28 15:23:00 +04:00
|
|
|
}
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const EffectPair & ep : loaded_effects) {
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!newLoaded.contains(ep.first)) // don't reconfigure newly loaded effects
|
|
|
|
ep.second->reconfigure(Effect::ReconfigureAll);
|
|
|
|
}
|
2012-04-13 13:36:48 +04:00
|
|
|
watcher->deleteLater();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-05-28 15:23:00 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
// the idea is that effects call this function again which calls the next one
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::prePaintScreen(ScreenPrePaintData& data, int time)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentPaintScreenIterator++)->prePaintScreen(data, time);
|
|
|
|
--m_currentPaintScreenIterator;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
// no special final code
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::paintScreen(int mask, QRegion region, ScreenPaintData& data)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentPaintScreenIterator++)->paintScreen(mask, region, data);
|
|
|
|
--m_currentPaintScreenIterator;
|
2011-01-30 17:34:42 +03:00
|
|
|
} else
|
2012-08-16 23:19:54 +04:00
|
|
|
m_scene->finalPaintScreen(mask, region, data);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2012-03-29 22:12:34 +04:00
|
|
|
void EffectsHandlerImpl::paintDesktop(int desktop, int mask, QRegion region, ScreenPaintData &data)
|
|
|
|
{
|
|
|
|
if (desktop < 1 || desktop > numberOfDesktops()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_currentRenderedDesktop = desktop;
|
|
|
|
m_desktopRendering = true;
|
|
|
|
// save the paint screen iterator
|
2013-07-19 13:34:01 +04:00
|
|
|
EffectsIterator savedIterator = m_currentPaintScreenIterator;
|
|
|
|
m_currentPaintScreenIterator = m_activeEffects.constBegin();
|
2012-03-29 22:12:34 +04:00
|
|
|
effects->paintScreen(mask, region, data);
|
|
|
|
// restore the saved iterator
|
|
|
|
m_currentPaintScreenIterator = savedIterator;
|
|
|
|
m_desktopRendering = false;
|
|
|
|
}
|
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
void EffectsHandlerImpl::postPaintScreen()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentPaintScreenIterator++)->postPaintScreen();
|
|
|
|
--m_currentPaintScreenIterator;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
// no special final code
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentPaintWindowIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentPaintWindowIterator++)->prePaintWindow(w, data, time);
|
|
|
|
--m_currentPaintWindowIterator;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
// no special final code
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentPaintWindowIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentPaintWindowIterator++)->paintWindow(w, mask, region, data);
|
|
|
|
--m_currentPaintWindowIterator;
|
2011-01-30 17:34:42 +03:00
|
|
|
} else
|
2012-08-16 23:19:54 +04:00
|
|
|
m_scene->finalPaintWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::paintEffectFrame(EffectFrame* frame, QRegion region, double opacity, double frameOpacity)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentPaintEffectFrameIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentPaintEffectFrameIterator++)->paintEffectFrame(frame, region, opacity, frameOpacity);
|
|
|
|
--m_currentPaintEffectFrameIterator;
|
2011-01-30 17:34:42 +03:00
|
|
|
} else {
|
|
|
|
const EffectFrameImpl* frameImpl = static_cast<const EffectFrameImpl*>(frame);
|
|
|
|
frameImpl->finalRender(region, opacity, frameOpacity);
|
2010-07-24 20:29:16 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-24 20:29:16 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::postPaintWindow(EffectWindow* w)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentPaintWindowIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentPaintWindowIterator++)->postPaintWindow(w);
|
|
|
|
--m_currentPaintWindowIterator;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
// no special final code
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2012-03-23 05:06:46 +04:00
|
|
|
Effect *EffectsHandlerImpl::provides(Effect::Feature ef)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
for (int i = 0; i < loaded_effects.size(); ++i)
|
|
|
|
if (loaded_effects.at(i).second->provides(ef))
|
2012-03-23 05:06:46 +04:00
|
|
|
return loaded_effects.at(i).second;
|
|
|
|
return NULL;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-04-25 22:40:04 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::drawWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentDrawWindowIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentDrawWindowIterator++)->drawWindow(w, mask, region, data);
|
|
|
|
--m_currentDrawWindowIterator;
|
2011-01-30 17:34:42 +03:00
|
|
|
} else
|
2012-08-16 23:19:54 +04:00
|
|
|
m_scene->finalDrawWindow(static_cast<EffectWindowImpl*>(w), mask, region, data);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::buildQuads(EffectWindow* w, WindowQuadList& quadList)
|
|
|
|
{
|
2012-05-08 00:29:54 +04:00
|
|
|
static bool initIterator = true;
|
|
|
|
if (initIterator) {
|
2013-07-19 13:34:01 +04:00
|
|
|
m_currentBuildQuadsIterator = m_activeEffects.constBegin();
|
2012-05-08 00:29:54 +04:00
|
|
|
initIterator = false;
|
|
|
|
}
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentBuildQuadsIterator != m_activeEffects.constEnd()) {
|
2011-08-27 13:21:31 +04:00
|
|
|
(*m_currentBuildQuadsIterator++)->buildQuads(w, quadList);
|
|
|
|
--m_currentBuildQuadsIterator;
|
2008-10-17 14:30:43 +04:00
|
|
|
}
|
2013-07-19 13:34:01 +04:00
|
|
|
if (m_currentBuildQuadsIterator == m_activeEffects.constBegin())
|
2012-05-08 00:29:54 +04:00
|
|
|
initIterator = true;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-10-17 14:30:43 +04:00
|
|
|
|
|
|
|
bool EffectsHandlerImpl::hasDecorationShadows() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-04-08 14:31:16 +04:00
|
|
|
return decorationPlugin()->hasShadows();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-10-17 14:30:43 +04:00
|
|
|
|
2010-03-05 21:21:14 +03:00
|
|
|
bool EffectsHandlerImpl::decorationsHaveAlpha() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-04-08 14:31:16 +04:00
|
|
|
return decorationPlugin()->hasAlpha();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-03-05 21:21:14 +03:00
|
|
|
|
2010-11-10 21:33:07 +03:00
|
|
|
bool EffectsHandlerImpl::decorationSupportsBlurBehind() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-04-08 14:31:16 +04:00
|
|
|
return decorationPlugin()->supportsBlurBehind();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-11-10 21:33:07 +03:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
// start another painting pass
|
|
|
|
void EffectsHandlerImpl::startPaint()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-08-27 13:21:31 +04:00
|
|
|
m_activeEffects.clear();
|
2013-07-19 13:46:42 +04:00
|
|
|
m_activeEffects.reserve(loaded_effects.count());
|
2013-07-19 13:34:01 +04:00
|
|
|
for(QVector< KWin::EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
|
2011-08-27 13:21:31 +04:00
|
|
|
if (it->second->isActive()) {
|
|
|
|
m_activeEffects << it->second;
|
|
|
|
}
|
|
|
|
}
|
2013-07-19 13:34:01 +04:00
|
|
|
m_currentDrawWindowIterator = m_activeEffects.constBegin();
|
|
|
|
m_currentPaintWindowIterator = m_activeEffects.constBegin();
|
|
|
|
m_currentPaintScreenIterator = m_activeEffects.constBegin();
|
|
|
|
m_currentPaintEffectFrameIterator = m_activeEffects.constBegin();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-02-28 23:03:13 +03:00
|
|
|
void EffectsHandlerImpl::slotClientMaximized(KWin::Client *c, KDecorationDefines::MaximizeMode maxMode)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-03-13 11:48:51 +03:00
|
|
|
bool horizontal = false;
|
|
|
|
bool vertical = false;
|
|
|
|
switch (maxMode) {
|
|
|
|
case KDecorationDefines::MaximizeHorizontal:
|
|
|
|
horizontal = true;
|
|
|
|
break;
|
|
|
|
case KDecorationDefines::MaximizeVertical:
|
|
|
|
vertical = true;
|
|
|
|
break;
|
|
|
|
case KDecorationDefines::MaximizeFull:
|
|
|
|
horizontal = true;
|
|
|
|
vertical = true;
|
|
|
|
break;
|
|
|
|
case KDecorationDefines::MaximizeRestore: // fall through
|
|
|
|
default:
|
|
|
|
// default - nothing to do
|
|
|
|
break;
|
|
|
|
}
|
2013-05-07 11:46:40 +04:00
|
|
|
if (EffectWindowImpl *w = c->effectWindow()) {
|
|
|
|
emit windowMaximizedStateChanged(w, horizontal, vertical);
|
|
|
|
}
|
2011-02-28 23:03:13 +03:00
|
|
|
}
|
|
|
|
|
2011-03-13 14:41:30 +03:00
|
|
|
void EffectsHandlerImpl::slotClientStartUserMovedResized(Client *c)
|
2011-02-28 23:03:13 +03:00
|
|
|
{
|
2011-03-13 14:41:30 +03:00
|
|
|
emit windowStartUserMovedResized(c->effectWindow());
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-03-13 14:41:30 +03:00
|
|
|
void EffectsHandlerImpl::slotClientFinishUserMovedResized(Client *c)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-03-13 14:41:30 +03:00
|
|
|
emit windowFinishUserMovedResized(c->effectWindow());
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectsHandlerImpl::slotClientStepUserMovedResized(Client* c, const QRect& geometry)
|
|
|
|
{
|
|
|
|
emit windowStepUserMovedResized(c->effectWindow(), geometry);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-10-30 17:22:33 +03:00
|
|
|
|
2011-03-06 12:30:23 +03:00
|
|
|
void EffectsHandlerImpl::slotOpacityChanged(Toplevel *t, qreal oldOpacity)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-15 21:34:12 +04:00
|
|
|
if (t->opacity() == oldOpacity || !t->effectWindow()) {
|
2007-04-29 21:35:43 +04:00
|
|
|
return;
|
2011-03-06 12:30:23 +03:00
|
|
|
}
|
|
|
|
emit windowOpacityChanged(t->effectWindow(), oldOpacity, (qreal)t->opacity());
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-02-26 00:06:02 +03:00
|
|
|
void EffectsHandlerImpl::slotClientAdded(Client *c)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-01-24 20:00:40 +04:00
|
|
|
if (c->readyForPainting())
|
|
|
|
slotClientShown(c);
|
|
|
|
else
|
|
|
|
connect(c, SIGNAL(windowShown(KWin::Toplevel*)), SLOT(slotClientShown(KWin::Toplevel*)));
|
2011-02-26 00:06:02 +03:00
|
|
|
}
|
|
|
|
|
2012-10-31 21:01:31 +04:00
|
|
|
void EffectsHandlerImpl::slotUnmanagedAdded(Unmanaged *u)
|
2013-06-28 16:23:22 +04:00
|
|
|
{
|
|
|
|
// it's never initially ready but has synthetic 50ms delay
|
|
|
|
connect(u, SIGNAL(windowShown(KWin::Toplevel*)), SLOT(slotUnmanagedShown(KWin::Toplevel*)));
|
2012-10-31 21:01:31 +04:00
|
|
|
}
|
|
|
|
|
2012-01-12 10:42:55 +04:00
|
|
|
void EffectsHandlerImpl::slotClientShown(KWin::Toplevel *t)
|
2012-01-24 20:00:40 +04:00
|
|
|
{
|
2012-01-12 10:42:55 +04:00
|
|
|
Q_ASSERT(dynamic_cast<Client*>(t));
|
|
|
|
Client *c = static_cast<Client*>(t);
|
|
|
|
setupClientConnections(c);
|
|
|
|
if (!c->tabGroup()) // the "window" has already been there
|
|
|
|
emit windowAdded(c->effectWindow());
|
2012-01-24 20:00:40 +04:00
|
|
|
}
|
|
|
|
|
2013-06-28 16:23:22 +04:00
|
|
|
void EffectsHandlerImpl::slotUnmanagedShown(KWin::Toplevel *t)
|
|
|
|
{ // regardless, unmanaged windows are -yet?- not synced anyway
|
|
|
|
Q_ASSERT(dynamic_cast<Unmanaged*>(t));
|
|
|
|
Unmanaged *u = static_cast<Unmanaged*>(t);
|
|
|
|
setupUnmanagedConnections(u);
|
|
|
|
emit windowAdded(u->effectWindow());
|
|
|
|
}
|
|
|
|
|
2011-02-27 12:47:42 +03:00
|
|
|
void EffectsHandlerImpl::slotDeletedRemoved(KWin::Deleted *d)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-02-27 12:47:42 +03:00
|
|
|
emit windowDeleted(d->effectWindow());
|
|
|
|
elevated_windows.removeAll(d->effectWindow());
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-06-21 15:52:25 +04:00
|
|
|
void EffectsHandlerImpl::slotWindowClosed(KWin::Toplevel *c)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-12-29 20:02:09 +04:00
|
|
|
c->disconnect(this);
|
2011-02-27 11:25:45 +03:00
|
|
|
emit windowClosed(c->effectWindow());
|
|
|
|
}
|
|
|
|
|
2011-02-27 12:05:04 +03:00
|
|
|
void EffectsHandlerImpl::slotClientActivated(KWin::Client *c)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-02-27 12:05:04 +03:00
|
|
|
emit windowActivated(c ? c->effectWindow() : NULL);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-03-06 12:55:27 +03:00
|
|
|
void EffectsHandlerImpl::slotClientMinimized(Client *c, bool animate)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-03-06 12:55:27 +03:00
|
|
|
// TODO: notify effects even if it should not animate?
|
|
|
|
if (animate) {
|
|
|
|
emit windowMinimized(c->effectWindow());
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-03-06 13:08:19 +03:00
|
|
|
void EffectsHandlerImpl::slotClientUnminimized(Client* c, bool animate)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-03-06 13:08:19 +03:00
|
|
|
// TODO: notify effects even if it should not animate?
|
|
|
|
if (animate) {
|
|
|
|
emit windowUnminimized(c->effectWindow());
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-06-19 18:26:55 +04:00
|
|
|
void EffectsHandlerImpl::slotClientModalityChanged()
|
|
|
|
{
|
|
|
|
emit windowModalityChanged(static_cast<Client*>(sender())->effectWindow());
|
|
|
|
}
|
|
|
|
|
2012-01-12 10:42:55 +04:00
|
|
|
void EffectsHandlerImpl::slotCurrentTabAboutToChange(EffectWindow *from, EffectWindow *to)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-01-12 10:42:55 +04:00
|
|
|
emit currentTabAboutToChange(from, to);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-11-15 06:24:04 +03:00
|
|
|
|
2012-01-12 10:42:55 +04:00
|
|
|
void EffectsHandlerImpl::slotTabAdded(EffectWindow* w, EffectWindow* to)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-01-12 10:42:55 +04:00
|
|
|
emit tabAdded(w, to);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-11-15 06:24:04 +03:00
|
|
|
|
2012-01-12 10:42:55 +04:00
|
|
|
void EffectsHandlerImpl::slotTabRemoved(EffectWindow *w, EffectWindow* leaderOfFormerGroup)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-01-12 10:42:55 +04:00
|
|
|
emit tabRemoved(w, leaderOfFormerGroup);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-11-15 06:24:04 +03:00
|
|
|
|
2012-05-02 23:16:16 +04:00
|
|
|
void EffectsHandlerImpl::slotDesktopChanged(int old, Client *c)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
const int newDesktop = VirtualDesktopManager::self()->current();
|
2011-02-25 22:41:10 +03:00
|
|
|
if (old != 0 && newDesktop != old) {
|
2012-05-02 23:16:16 +04:00
|
|
|
emit desktopChanged(old, newDesktop, c ? c->effectWindow() : 0);
|
|
|
|
// TODO: remove in 4.10
|
2011-02-25 22:41:10 +03:00
|
|
|
emit desktopChanged(old, newDesktop);
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-03-12 17:04:22 +03:00
|
|
|
void EffectsHandlerImpl::slotWindowDamaged(Toplevel* t, const QRect& r)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-05-19 19:28:15 +04:00
|
|
|
if (!t->effectWindow()) {
|
|
|
|
// can happen during tear down of window
|
|
|
|
return;
|
|
|
|
}
|
2011-03-12 17:04:22 +03:00
|
|
|
emit windowDamaged(t->effectWindow(), r);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-06-20 00:07:19 +04:00
|
|
|
void EffectsHandlerImpl::slotGeometryShapeChanged(Toplevel* t, const QRect& old)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-03-12 14:34:59 +03:00
|
|
|
// during late cleanup effectWindow() may be already NULL
|
|
|
|
// in some functions that may still call this
|
2011-06-20 00:07:19 +04:00
|
|
|
if (t == NULL || t->effectWindow() == NULL)
|
2011-03-12 14:34:59 +03:00
|
|
|
return;
|
2011-06-20 00:07:19 +04:00
|
|
|
emit windowGeometryShapeChanged(t->effectWindow(), old);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2012-03-25 01:42:29 +04:00
|
|
|
void EffectsHandlerImpl::slotPaddingChanged(Toplevel* t, const QRect& old)
|
|
|
|
{
|
|
|
|
// during late cleanup effectWindow() may be already NULL
|
|
|
|
// in some functions that may still call this
|
|
|
|
if (t == NULL || t->effectWindow() == NULL)
|
|
|
|
return;
|
|
|
|
emit windowPaddingChanged(t->effectWindow(), old);
|
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::setActiveFullScreenEffect(Effect* e)
|
|
|
|
{
|
2007-11-01 20:47:41 +03:00
|
|
|
fullscreen_effect = e;
|
2012-08-23 20:04:36 +04:00
|
|
|
m_compositor->checkUnredirect();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-01 20:47:41 +03:00
|
|
|
|
|
|
|
Effect* EffectsHandlerImpl::activeFullScreenEffect() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-11-01 20:47:41 +03:00
|
|
|
return fullscreen_effect;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-01 20:47:41 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
bool EffectsHandlerImpl::grabKeyboard(Effect* effect)
|
|
|
|
{
|
|
|
|
if (keyboard_grab_effect != NULL)
|
2007-04-29 21:35:43 +04:00
|
|
|
return false;
|
|
|
|
bool ret = grabXKeyboard();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!ret)
|
2007-04-29 21:35:43 +04:00
|
|
|
return false;
|
|
|
|
keyboard_grab_effect = effect;
|
|
|
|
return true;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::ungrabKeyboard()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
assert(keyboard_grab_effect != NULL);
|
2007-04-29 21:35:43 +04:00
|
|
|
ungrabXKeyboard();
|
|
|
|
keyboard_grab_effect = NULL;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::grabbedKeyboardEvent(QKeyEvent* e)
|
|
|
|
{
|
|
|
|
if (keyboard_grab_effect != NULL)
|
|
|
|
keyboard_grab_effect->grabbedKeyboardEvent(e);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-04-24 18:51:04 +04:00
|
|
|
void EffectsHandlerImpl::startMouseInterception(Effect *effect, Qt::CursorShape shape)
|
|
|
|
{
|
|
|
|
if (m_grabbedMouseEffects.contains(effect)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_grabbedMouseEffects.append(effect);
|
|
|
|
if (m_grabbedMouseEffects.size() != 1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// NOTE: it is intended to not perform an XPointerGrab on X11. See documentation in kwineffects.h
|
|
|
|
// The mouse grab is implemented by using a full screen input only window
|
|
|
|
if (!m_mouseInterceptionWindow.isValid()) {
|
|
|
|
const QRect geo(0, 0, displayWidth(), displayHeight());
|
|
|
|
const uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
|
|
|
|
const uint32_t values[] = {
|
|
|
|
true,
|
|
|
|
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION,
|
|
|
|
Cursor::x11Cursor(shape)
|
|
|
|
};
|
|
|
|
m_mouseInterceptionWindow.reset(Xcb::createInputWindow(geo, mask, values));
|
|
|
|
}
|
|
|
|
m_mouseInterceptionWindow.map();
|
|
|
|
m_mouseInterceptionWindow.raise();
|
|
|
|
// Raise electric border windows above the input windows
|
|
|
|
// so they can still be triggered.
|
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
|
|
|
ScreenEdges::self()->ensureOnTop();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectsHandlerImpl::stopMouseInterception(Effect *effect)
|
|
|
|
{
|
|
|
|
if (!m_grabbedMouseEffects.contains(effect)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_grabbedMouseEffects.removeAll(effect);
|
|
|
|
if (m_grabbedMouseEffects.isEmpty()) {
|
|
|
|
m_mouseInterceptionWindow.unmap();
|
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
|
|
|
Workspace::self()->stackScreenEdgesUnderOverrideRedirect();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void* EffectsHandlerImpl::getProxy(QString name)
|
|
|
|
{
|
2009-02-06 13:15:06 +03:00
|
|
|
// All effects start with "kwin4_effect_", prepend it to the name
|
2013-07-23 09:02:52 +04:00
|
|
|
name.prepend(QStringLiteral("kwin4_effect_"));
|
2009-02-06 13:15:06 +03:00
|
|
|
|
2013-07-19 13:34:01 +04:00
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it)
|
2011-01-30 17:34:42 +03:00
|
|
|
if ((*it).first == name)
|
2009-02-06 13:15:06 +03:00
|
|
|
return (*it).second->proxy();
|
|
|
|
|
|
|
|
return NULL;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-06 13:15:06 +03:00
|
|
|
|
2009-02-01 18:16:52 +03:00
|
|
|
void EffectsHandlerImpl::startMousePolling()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-02-19 14:25:46 +04:00
|
|
|
Cursor::self()->startMousePolling();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-01 18:16:52 +03:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::stopMousePolling()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-02-19 14:25:46 +04:00
|
|
|
Cursor::self()->stopMousePolling();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-01 18:16:52 +03:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
bool EffectsHandlerImpl::hasKeyboardGrab() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
return keyboard_grab_effect != NULL;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-11-26 19:15:46 +04:00
|
|
|
void EffectsHandlerImpl::desktopResized(const QSize &size)
|
|
|
|
{
|
2012-08-16 23:19:54 +04:00
|
|
|
m_scene->screenGeometryChanged(size);
|
2013-04-24 18:51:04 +04:00
|
|
|
if (m_mouseInterceptionWindow.isValid()) {
|
|
|
|
m_mouseInterceptionWindow.setGeometry(QRect(0, 0, size.width(), size.height()));
|
|
|
|
}
|
2011-11-26 19:15:46 +04:00
|
|
|
emit screenGeometryChanged(size);
|
|
|
|
}
|
|
|
|
|
2011-03-12 21:18:19 +03:00
|
|
|
void EffectsHandlerImpl::slotPropertyNotify(Toplevel* t, long int atom)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (!registered_atoms.contains(atom))
|
2008-01-02 18:21:33 +03:00
|
|
|
return;
|
2011-03-12 21:18:19 +03:00
|
|
|
emit propertyNotify(t->effectWindow(), atom);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectsHandlerImpl::slotPropertyNotify(long int atom)
|
|
|
|
{
|
|
|
|
if (!registered_atoms.contains(atom))
|
|
|
|
return;
|
|
|
|
emit propertyNotify(NULL, atom);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-01-02 18:21:33 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::registerPropertyType(long atom, bool reg)
|
|
|
|
{
|
|
|
|
if (reg)
|
2008-01-02 18:21:33 +03:00
|
|
|
++registered_atoms[ atom ]; // initialized to 0 if not present yet
|
2011-01-30 17:34:42 +03:00
|
|
|
else {
|
|
|
|
if (--registered_atoms[ atom ] == 0)
|
|
|
|
registered_atoms.remove(atom);
|
2008-01-02 18:21:33 +03:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-01-02 18:21:33 +03:00
|
|
|
|
2012-12-14 03:09:47 +04:00
|
|
|
xcb_atom_t EffectsHandlerImpl::announceSupportProperty(const QByteArray &propertyName, Effect *effect)
|
|
|
|
{
|
|
|
|
PropertyEffectMap::iterator it = m_propertiesForEffects.find(propertyName);
|
|
|
|
if (it != m_propertiesForEffects.end()) {
|
|
|
|
// property has already been registered for an effect
|
|
|
|
// just append Effect and return the atom stored in m_managedProperties
|
|
|
|
if (!it.value().contains(effect)) {
|
|
|
|
it.value().append(effect);
|
|
|
|
}
|
|
|
|
return m_managedProperties.value(propertyName);
|
|
|
|
}
|
|
|
|
// get the atom for the propertyName
|
2013-06-21 20:45:19 +04:00
|
|
|
ScopedCPointer<xcb_intern_atom_reply_t> atomReply(xcb_intern_atom_reply(connection(),
|
2012-12-14 03:09:47 +04:00
|
|
|
xcb_intern_atom_unchecked(connection(), false, propertyName.size(), propertyName.constData()),
|
|
|
|
NULL));
|
|
|
|
if (atomReply.isNull()) {
|
|
|
|
return XCB_ATOM_NONE;
|
|
|
|
}
|
2013-04-27 02:00:23 +04:00
|
|
|
m_compositor->keepSupportProperty(atomReply->atom);
|
2012-12-14 03:09:47 +04:00
|
|
|
// announce property on root window
|
|
|
|
unsigned char dummy = 0;
|
|
|
|
xcb_change_property(connection(), XCB_PROP_MODE_REPLACE, rootWindow(), atomReply->atom, atomReply->atom, 8, 1, &dummy);
|
|
|
|
// TODO: add to _NET_SUPPORTED
|
|
|
|
m_managedProperties.insert(propertyName, atomReply->atom);
|
|
|
|
m_propertiesForEffects.insert(propertyName, QList<Effect*>() << effect);
|
|
|
|
registerPropertyType(atomReply->atom, true);
|
|
|
|
return atomReply->atom;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectsHandlerImpl::removeSupportProperty(const QByteArray &propertyName, Effect *effect)
|
|
|
|
{
|
|
|
|
PropertyEffectMap::iterator it = m_propertiesForEffects.find(propertyName);
|
|
|
|
if (it == m_propertiesForEffects.end()) {
|
|
|
|
// property is not registered - nothing to do
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!it.value().contains(effect)) {
|
|
|
|
// property is not registered for given effect - nothing to do
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
it.value().removeAll(effect);
|
|
|
|
if (!it.value().isEmpty()) {
|
|
|
|
// property still registered for another effect - nothing further to do
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const xcb_atom_t atom = m_managedProperties.take(propertyName);
|
|
|
|
registerPropertyType(atom, false);
|
|
|
|
m_propertiesForEffects.remove(propertyName);
|
2013-04-27 02:00:23 +04:00
|
|
|
m_compositor->removeSupportProperty(atom); // delayed removal
|
2012-12-14 03:09:47 +04:00
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QByteArray EffectsHandlerImpl::readRootProperty(long atom, long type, int format) const
|
|
|
|
{
|
|
|
|
return readWindowProperty(rootWindow(), atom, type, format);
|
|
|
|
}
|
2010-02-01 10:44:27 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::deleteRootProperty(long atom) const
|
|
|
|
{
|
|
|
|
deleteWindowProperty(rootWindow(), atom);
|
|
|
|
}
|
2010-02-01 10:44:27 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::activateWindow(EffectWindow* c)
|
|
|
|
{
|
|
|
|
if (Client* cl = dynamic_cast< Client* >(static_cast<EffectWindowImpl*>(c)->window()))
|
|
|
|
Workspace::self()->activateClient(cl, true);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
EffectWindow* EffectsHandlerImpl::activeWindow() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
return Workspace::self()->activeClient() ? Workspace::self()->activeClient()->effectWindow() : NULL;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::moveWindow(EffectWindow* w, const QPoint& pos, bool snap, double snapAdjust)
|
|
|
|
{
|
|
|
|
Client* cl = dynamic_cast< Client* >(static_cast<EffectWindowImpl*>(w)->window());
|
2009-10-05 08:06:20 +04:00
|
|
|
if (!cl || !cl->isMovable())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (snap)
|
|
|
|
cl->move(Workspace::self()->adjustClientPosition(cl, pos, true, snapAdjust));
|
|
|
|
else
|
2011-01-30 17:34:42 +03:00
|
|
|
cl->move(pos);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::windowToDesktop(EffectWindow* w, int desktop)
|
|
|
|
{
|
|
|
|
Client* cl = dynamic_cast< Client* >(static_cast<EffectWindowImpl*>(w)->window());
|
2011-06-24 14:19:47 +04:00
|
|
|
if (cl && !cl->isDesktop() && !cl->isDock())
|
2011-01-30 17:34:42 +03:00
|
|
|
Workspace::self()->sendClientToDesktop(cl, desktop, true);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::windowToScreen(EffectWindow* w, int screen)
|
|
|
|
{
|
|
|
|
Client* cl = dynamic_cast< Client* >(static_cast<EffectWindowImpl*>(w)->window());
|
2011-06-24 14:19:47 +04:00
|
|
|
if (cl && !cl->isDesktop() && !cl->isDock())
|
2011-01-30 17:34:42 +03:00
|
|
|
Workspace::self()->sendClientToScreen(cl, screen);
|
|
|
|
}
|
2009-11-19 11:34:28 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::setShowingDesktop(bool showing)
|
|
|
|
{
|
|
|
|
Workspace::self()->setShowingDesktop(showing);
|
|
|
|
}
|
2009-06-28 21:17:29 +04:00
|
|
|
|
2011-04-24 16:20:47 +04:00
|
|
|
QString EffectsHandlerImpl::currentActivity() const
|
|
|
|
{
|
2013-04-04 18:14:12 +04:00
|
|
|
#ifdef KWIN_BUILD_ACTIVITIES
|
|
|
|
return Activities::self()->current();
|
|
|
|
#else
|
|
|
|
return QString();
|
|
|
|
#endif
|
2011-04-24 16:20:47 +04:00
|
|
|
}
|
2009-06-28 21:17:29 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
int EffectsHandlerImpl::currentDesktop() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return VirtualDesktopManager::self()->current();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
int EffectsHandlerImpl::numberOfDesktops() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return VirtualDesktopManager::self()->count();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::setCurrentDesktop(int desktop)
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
VirtualDesktopManager::self()->setCurrent(desktop);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::setNumberOfDesktops(int desktops)
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
VirtualDesktopManager::self()->setCount(desktops);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-03-28 13:04:14 +04:00
|
|
|
|
2009-02-14 17:49:46 +03:00
|
|
|
QSize EffectsHandlerImpl::desktopGridSize() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return VirtualDesktopManager::self()->grid().size();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2009-02-14 17:49:46 +03:00
|
|
|
int EffectsHandlerImpl::desktopGridWidth() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return desktopGridSize().width();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2009-02-14 17:49:46 +03:00
|
|
|
int EffectsHandlerImpl::desktopGridHeight() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return desktopGridSize().height();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2009-02-14 17:49:46 +03:00
|
|
|
int EffectsHandlerImpl::workspaceWidth() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return desktopGridWidth() * displayWidth();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-14 17:49:46 +03:00
|
|
|
|
|
|
|
int EffectsHandlerImpl::workspaceHeight() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return desktopGridHeight() * displayHeight();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-14 17:49:46 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
int EffectsHandlerImpl::desktopAtCoords(QPoint coords) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return VirtualDesktopManager::self()->grid().at(coords);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-14 17:49:46 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QPoint EffectsHandlerImpl::desktopGridCoords(int id) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return VirtualDesktopManager::self()->grid().gridCoords(id);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-14 17:49:46 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QPoint EffectsHandlerImpl::desktopCoords(int id) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
QPoint coords = VirtualDesktopManager::self()->grid().gridCoords(id);
|
|
|
|
if (coords.x() == -1)
|
|
|
|
return QPoint(-1, -1);
|
|
|
|
return QPoint(coords.x() * displayWidth(), coords.y() * displayHeight());
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-14 17:49:46 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
int EffectsHandlerImpl::desktopAbove(int desktop, bool wrap) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return getDesktop<DesktopAbove>(desktop, wrap);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-20 19:17:08 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
int EffectsHandlerImpl::desktopToRight(int desktop, bool wrap) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return getDesktop<DesktopRight>(desktop, wrap);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-20 19:17:08 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
int EffectsHandlerImpl::desktopBelow(int desktop, bool wrap) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return getDesktop<DesktopBelow>(desktop, wrap);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-20 19:17:08 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
int EffectsHandlerImpl::desktopToLeft(int desktop, bool wrap) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return getDesktop<DesktopLeft>(desktop, wrap);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-14 17:49:46 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QString EffectsHandlerImpl::desktopName(int desktop) const
|
|
|
|
{
|
2012-11-16 11:23:47 +04:00
|
|
|
return VirtualDesktopManager::self()->name(desktop);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2009-02-14 17:49:46 +03:00
|
|
|
|
|
|
|
bool EffectsHandlerImpl::optionRollOverDesktops() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-02-20 13:25:13 +04:00
|
|
|
return options->isRollOverDesktops();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-20 19:17:08 +03:00
|
|
|
|
2008-08-30 11:25:54 +04:00
|
|
|
double EffectsHandlerImpl::animationTimeFactor() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2008-08-30 11:25:54 +04:00
|
|
|
return options->animationTimeFactor();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-08-30 11:25:54 +04:00
|
|
|
|
2008-10-17 14:30:43 +04:00
|
|
|
WindowQuadType EffectsHandlerImpl::newWindowQuadType()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
return WindowQuadType(next_window_quad_type++);
|
|
|
|
}
|
2008-10-17 14:30:43 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
int EffectsHandlerImpl::displayWidth() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
return KWin::displayWidth();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
int EffectsHandlerImpl::displayHeight() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-09-02 00:30:11 +04:00
|
|
|
return KWin::displayHeight();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
EffectWindow* EffectsHandlerImpl::findWindow(WId id) const
|
|
|
|
{
|
|
|
|
if (Client* w = Workspace::self()->findClient(WindowMatchPredicate(id)))
|
2008-01-02 18:37:46 +03:00
|
|
|
return w->effectWindow();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (Unmanaged* w = Workspace::self()->findUnmanaged(WindowMatchPredicate(id)))
|
2008-01-02 18:37:46 +03:00
|
|
|
return w->effectWindow();
|
|
|
|
return NULL;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-01-02 18:37:46 +03:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindowList EffectsHandlerImpl::stackingOrder() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-05-02 00:56:37 +04:00
|
|
|
ToplevelList list = Workspace::self()->xStackingOrder();
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindowList ret;
|
2013-09-24 16:31:35 +04:00
|
|
|
for (Toplevel *t : list) {
|
2013-07-02 14:45:01 +04:00
|
|
|
if (EffectWindow *w = effectWindow(t))
|
|
|
|
ret.append(w);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
return ret;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::setElevatedWindow(EffectWindow* w, bool set)
|
|
|
|
{
|
|
|
|
elevated_windows.removeAll(w);
|
|
|
|
if (set)
|
|
|
|
elevated_windows.append(w);
|
|
|
|
}
|
2007-05-24 18:41:56 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
void EffectsHandlerImpl::setTabBoxWindow(EffectWindow* w)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
|
|
|
if (Client* c = dynamic_cast< Client* >(static_cast< EffectWindowImpl* >(w)->window())) {
|
2013-04-04 11:41:18 +04:00
|
|
|
TabBox::TabBox::self()->setCurrentClient(c);
|
2011-06-30 15:02:30 +04:00
|
|
|
}
|
2011-07-07 20:31:18 +04:00
|
|
|
#else
|
|
|
|
Q_UNUSED(w)
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::setTabBoxDesktop(int desktop)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
TabBox::TabBox::self()->setCurrentDesktop(desktop);
|
2011-07-07 20:31:18 +04:00
|
|
|
#else
|
|
|
|
Q_UNUSED(desktop)
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
EffectWindowList EffectsHandlerImpl::currentTabBoxWindowList() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindowList ret;
|
2011-06-25 20:05:07 +04:00
|
|
|
ClientList clients;
|
2013-04-04 11:41:18 +04:00
|
|
|
clients = TabBox::TabBox::self()->currentClientList();
|
2013-09-24 16:31:35 +04:00
|
|
|
for (Client * c : clients)
|
2011-01-30 17:34:42 +03:00
|
|
|
ret.append(c->effectWindow());
|
2007-04-29 21:35:43 +04:00
|
|
|
return ret;
|
2011-06-30 15:02:30 +04:00
|
|
|
#else
|
2011-07-06 19:42:07 +04:00
|
|
|
return EffectWindowList();
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::refTabBox()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
TabBox::TabBox::self()->reference();
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::unrefTabBox()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
TabBox::TabBox::self()->unreference();
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::closeTabBox()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
TabBox::TabBox::self()->close();
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
QList< int > EffectsHandlerImpl::currentTabBoxDesktopList() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
return TabBox::TabBox::self()->currentDesktopList();
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-06-25 20:05:07 +04:00
|
|
|
return QList< int >();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
int EffectsHandlerImpl::currentTabBoxDesktop() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
return TabBox::TabBox::self()->currentDesktop();
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2011-06-25 20:05:07 +04:00
|
|
|
return -1;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
EffectWindow* EffectsHandlerImpl::currentTabBoxWindow() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-06-30 15:02:30 +04:00
|
|
|
#ifdef KWIN_BUILD_TABBOX
|
2013-04-04 11:41:18 +04:00
|
|
|
if (Client* c = TabBox::TabBox::self()->currentClient())
|
2007-04-29 21:35:43 +04:00
|
|
|
return c->effectWindow();
|
2011-06-30 15:02:30 +04:00
|
|
|
#endif
|
2007-04-29 21:35:43 +04:00
|
|
|
return NULL;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::addRepaintFull()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-08-23 20:04:36 +04:00
|
|
|
m_compositor->addRepaintFull();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::addRepaint(const QRect& r)
|
|
|
|
{
|
2012-08-23 20:04:36 +04:00
|
|
|
m_compositor->addRepaint(r);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::addRepaint(const QRegion& r)
|
|
|
|
{
|
2012-08-23 20:04:36 +04:00
|
|
|
m_compositor->addRepaint(r);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-06-19 18:16:21 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::addRepaint(int x, int y, int w, int h)
|
|
|
|
{
|
2012-08-23 20:04:36 +04:00
|
|
|
m_compositor->addRepaint(x, y, w, h);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2007-11-20 21:58:30 +03:00
|
|
|
int EffectsHandlerImpl::activeScreen() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-04-03 14:19:27 +04:00
|
|
|
return screens()->current();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-20 21:58:30 +03:00
|
|
|
|
2008-06-09 20:09:56 +04:00
|
|
|
int EffectsHandlerImpl::numScreens() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-04-03 14:19:27 +04:00
|
|
|
return screens()->count();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-06-09 20:09:56 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
int EffectsHandlerImpl::screenNumber(const QPoint& pos) const
|
|
|
|
{
|
2013-04-03 14:19:27 +04:00
|
|
|
return screens()->number(pos);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2008-06-19 18:16:21 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QRect EffectsHandlerImpl::clientArea(clientAreaOption opt, int screen, int desktop) const
|
|
|
|
{
|
|
|
|
return Workspace::self()->clientArea(opt, screen, desktop);
|
|
|
|
}
|
2007-11-20 21:58:30 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QRect EffectsHandlerImpl::clientArea(clientAreaOption opt, const EffectWindow* c) const
|
|
|
|
{
|
2007-11-20 21:58:30 +03:00
|
|
|
const Toplevel* t = static_cast< const EffectWindowImpl* >(c)->window();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (const Client* cl = dynamic_cast< const Client* >(t))
|
|
|
|
return Workspace::self()->clientArea(opt, cl);
|
2007-11-20 21:58:30 +03:00
|
|
|
else
|
2012-11-16 11:23:47 +04:00
|
|
|
return Workspace::self()->clientArea(opt, t->geometry().center(), VirtualDesktopManager::self()->current());
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-11-20 21:58:30 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QRect EffectsHandlerImpl::clientArea(clientAreaOption opt, const QPoint& p, int desktop) const
|
|
|
|
{
|
|
|
|
return Workspace::self()->clientArea(opt, p, desktop);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-04-24 18:51:04 +04:00
|
|
|
void EffectsHandlerImpl::defineCursor(Qt::CursorShape shape)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-04-24 18:51:04 +04:00
|
|
|
if (!m_mouseInterceptionWindow.isValid()) {
|
|
|
|
return;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2013-04-24 18:51:04 +04:00
|
|
|
m_mouseInterceptionWindow.defineCursor(Cursor::x11Cursor(shape));
|
2013-02-19 21:35:23 +04:00
|
|
|
}
|
|
|
|
|
2013-07-26 10:46:31 +04:00
|
|
|
bool EffectsHandlerImpl::checkInputWindowEvent(xcb_button_press_event_t *e)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-07-26 10:46:31 +04:00
|
|
|
if (m_grabbedMouseEffects.isEmpty() || m_mouseInterceptionWindow != e->event) {
|
2007-04-29 21:35:43 +04:00
|
|
|
return false;
|
2013-07-26 10:46:31 +04:00
|
|
|
}
|
|
|
|
for (Effect *effect : m_grabbedMouseEffects) {
|
|
|
|
Qt::MouseButton button = x11ToQtMouseButton(e->detail);
|
2013-08-06 14:19:20 +04:00
|
|
|
Qt::MouseButtons buttons = x11ToQtMouseButtons(e->state);
|
|
|
|
const QEvent::Type type = ((e->response_type & ~0x80) == XCB_BUTTON_PRESS) ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
|
|
|
|
if (type == QEvent::MouseButtonPress) {
|
|
|
|
buttons |= button;
|
|
|
|
} else {
|
|
|
|
buttons &= ~button;
|
|
|
|
}
|
|
|
|
QMouseEvent ev(type,
|
2013-07-26 10:46:31 +04:00
|
|
|
QPoint(e->event_x, e->event_y), QPoint(e->root_x, e->root_y),
|
|
|
|
button, buttons, x11ToQtKeyboardModifiers(e->state));
|
|
|
|
effect->windowInputMouseEvent(&ev);
|
|
|
|
}
|
|
|
|
return true; // eat event
|
|
|
|
}
|
|
|
|
|
|
|
|
bool EffectsHandlerImpl::checkInputWindowEvent(xcb_motion_notify_event_t *e)
|
|
|
|
{
|
|
|
|
if (m_grabbedMouseEffects.isEmpty() || m_mouseInterceptionWindow != e->event) {
|
2013-04-24 18:51:04 +04:00
|
|
|
return false;
|
|
|
|
}
|
2013-07-26 10:46:31 +04:00
|
|
|
for (Effect *effect : m_grabbedMouseEffects) {
|
|
|
|
QMouseEvent ev(QEvent::MouseMove, QPoint(e->event_x, e->event_y), QPoint(e->root_x, e->root_y),
|
|
|
|
Qt::NoButton, x11ToQtMouseButtons(e->state), x11ToQtKeyboardModifiers(e->state));
|
|
|
|
effect->windowInputMouseEvent(&ev);
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2013-04-24 18:51:04 +04:00
|
|
|
return true; // eat event
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectsHandlerImpl::checkInputWindowStacking()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-04-24 18:51:04 +04:00
|
|
|
if (m_grabbedMouseEffects.isEmpty()) {
|
2007-04-29 21:35:43 +04:00
|
|
|
return;
|
2012-07-16 23:57:11 +04:00
|
|
|
}
|
2013-04-24 18:51:04 +04:00
|
|
|
m_mouseInterceptionWindow.raise();
|
2009-02-06 17:21:20 +03:00
|
|
|
// Raise electric border windows above the input windows
|
|
|
|
// so they can still be triggered. TODO: Do both at once.
|
2011-07-07 20:29:11 +04:00
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
2013-04-24 18:51:04 +04:00
|
|
|
ScreenEdges::self()->ensureOnTop();
|
2011-07-07 20:29:11 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
QPoint EffectsHandlerImpl::cursorPos() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-02-19 14:25:46 +04:00
|
|
|
return Cursor::pos();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-01-22 15:47:06 +04:00
|
|
|
void EffectsHandlerImpl::reserveElectricBorder(ElectricBorder border, Effect *effect)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-07-07 20:29:11 +04:00
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
2013-01-25 13:15:00 +04:00
|
|
|
ScreenEdges::self()->reserve(border, effect, "borderActivated");
|
2011-07-07 20:29:11 +04:00
|
|
|
#else
|
|
|
|
Q_UNUSED(border)
|
2013-01-22 15:47:06 +04:00
|
|
|
Q_UNUSED(effect)
|
2011-07-07 20:29:11 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-01-22 15:47:06 +04:00
|
|
|
void EffectsHandlerImpl::unreserveElectricBorder(ElectricBorder border, Effect *effect)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2011-07-07 20:29:11 +04:00
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
2013-01-25 13:15:00 +04:00
|
|
|
ScreenEdges::self()->unreserve(border, effect);
|
2011-07-07 20:29:11 +04:00
|
|
|
#else
|
|
|
|
Q_UNUSED(border)
|
2013-01-22 15:47:06 +04:00
|
|
|
Q_UNUSED(effect)
|
2011-07-07 20:29:11 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
unsigned long EffectsHandlerImpl::xrenderBufferPicture()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-12-17 17:14:53 +03:00
|
|
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
2012-08-16 23:19:54 +04:00
|
|
|
if (SceneXrender* s = dynamic_cast< SceneXrender* >(m_scene))
|
2007-04-29 21:35:43 +04:00
|
|
|
return s->bufferPicture();
|
|
|
|
#endif
|
|
|
|
return None;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
KLibrary* EffectsHandlerImpl::findEffectLibrary(KService* service)
|
|
|
|
{
|
2007-07-06 16:38:41 +04:00
|
|
|
QString libname = service->library();
|
2011-07-17 21:46:16 +04:00
|
|
|
#ifdef KWIN_HAVE_OPENGLES
|
2013-07-23 09:02:52 +04:00
|
|
|
if (libname.startsWith(QStringLiteral("kwin4_effect_"))) {
|
|
|
|
libname.replace(QStringLiteral("kwin4_effect_"), QStringLiteral("kwin4_effect_gles_"));
|
2011-07-17 21:46:16 +04:00
|
|
|
}
|
|
|
|
#endif
|
2013-07-23 09:02:52 +04:00
|
|
|
libname.replace(QStringLiteral("kwin"), QStringLiteral(KWIN_NAME));
|
2009-10-05 13:47:13 +04:00
|
|
|
KLibrary* library = new KLibrary(libname);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!library) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qCritical() << "couldn't open library for effect '" <<
|
2011-01-30 17:34:42 +03:00
|
|
|
service->name() << "'" << endl;
|
2007-04-29 21:35:43 +04:00
|
|
|
return 0;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
return library;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::toggleEffect(const QString& name)
|
|
|
|
{
|
|
|
|
if (isEffectLoaded(name))
|
|
|
|
unloadEffect(name);
|
2007-05-29 15:42:47 +04:00
|
|
|
else
|
2011-01-30 17:34:42 +03:00
|
|
|
loadEffect(name);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2008-06-10 13:32:46 +04:00
|
|
|
QStringList EffectsHandlerImpl::loadedEffects() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2008-06-10 13:32:46 +04:00
|
|
|
QStringList listModules;
|
2011-01-30 17:34:42 +03:00
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
|
|
|
|
listModules << (*it).first;
|
2008-06-02 23:52:02 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
return listModules;
|
|
|
|
}
|
2008-06-02 23:52:02 +04:00
|
|
|
|
2008-06-10 13:32:46 +04:00
|
|
|
QStringList EffectsHandlerImpl::listOfEffects() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-07-23 09:02:52 +04:00
|
|
|
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("KWin/Effect"));
|
2008-06-10 13:32:46 +04:00
|
|
|
QStringList listOfModules;
|
|
|
|
// First unload necessary effects
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const KService::Ptr & service : offers) {
|
2011-01-30 17:34:42 +03:00
|
|
|
KPluginInfo plugininfo(service);
|
|
|
|
listOfModules << plugininfo.pluginName();
|
2008-06-03 00:05:17 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
return listOfModules;
|
|
|
|
}
|
2008-06-03 00:05:17 +04:00
|
|
|
|
2011-05-02 00:37:59 +04:00
|
|
|
bool EffectsHandlerImpl::loadEffect(const QString& name, bool checkDefault)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-08-23 20:04:36 +04:00
|
|
|
m_compositor->addRepaintFull();
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!name.startsWith(QLatin1String("kwin4_effect_")))
|
2013-09-02 15:14:39 +04:00
|
|
|
qWarning() << "Effect names usually have kwin4_effect_ prefix" ;
|
2007-05-28 15:12:20 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
// Make sure a single effect won't be loaded multiple times
|
2011-01-30 17:34:42 +03:00
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
|
|
|
|
if ((*it).first == name) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qDebug() << "EffectsHandler::loadEffect : Effect already loaded : " << name;
|
2007-07-21 01:13:10 +04:00
|
|
|
return true;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
|
2013-09-02 15:14:39 +04:00
|
|
|
qDebug() << "Trying to load " << name;
|
2007-07-06 16:38:41 +04:00
|
|
|
QString internalname = name.toLower();
|
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
QString constraint = QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(internalname);
|
|
|
|
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("KWin/Effect"), constraint);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (offers.isEmpty()) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qCritical() << "Couldn't find effect " << name << endl;
|
2007-07-21 01:13:10 +04:00
|
|
|
return false;
|
2007-07-06 16:38:41 +04:00
|
|
|
}
|
2007-07-21 22:30:06 +04:00
|
|
|
KService::Ptr service = offers.first();
|
2007-07-06 16:38:41 +04:00
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
if (service->property(QStringLiteral("X-Plasma-API")).toString() == QStringLiteral("javascript")) {
|
2012-01-29 20:32:56 +04:00
|
|
|
// this is a scripted effect - use different loader
|
|
|
|
return loadScriptedEffect(name, service.data());
|
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
KLibrary* library = findEffectLibrary(service.data());
|
|
|
|
if (!library) {
|
2007-07-21 01:13:10 +04:00
|
|
|
return false;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
QString version_symbol = QStringLiteral("effect_version_") + name;
|
|
|
|
KLibrary::void_function_ptr version_func = library->resolveFunction(version_symbol.toAscii().constData());
|
2011-01-30 17:34:42 +03:00
|
|
|
if (version_func == NULL) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qWarning() << "Effect " << name << " does not provide required API version, ignoring.";
|
2011-08-02 19:27:06 +04:00
|
|
|
delete library;
|
2007-12-17 17:10:21 +03:00
|
|
|
return false;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-12-17 17:10:21 +03:00
|
|
|
typedef int (*t_versionfunc)();
|
2011-01-30 17:34:42 +03:00
|
|
|
int version = reinterpret_cast< t_versionfunc >(version_func)(); // call it
|
2008-01-02 18:17:58 +03:00
|
|
|
// Version must be the same or less, but major must be the same.
|
2008-01-02 18:18:34 +03:00
|
|
|
// With major 0 minor must match exactly.
|
2011-01-30 17:34:42 +03:00
|
|
|
if (version > KWIN_EFFECT_API_VERSION
|
|
|
|
|| (version >> 8) != KWIN_EFFECT_API_VERSION_MAJOR
|
|
|
|
|| (KWIN_EFFECT_API_VERSION_MAJOR == 0 && version != KWIN_EFFECT_API_VERSION)) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qWarning() << "Effect " << name << " requires unsupported API version " << version;
|
2011-08-02 19:27:06 +04:00
|
|
|
delete library;
|
2007-12-17 17:10:21 +03:00
|
|
|
return false;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2011-05-02 00:37:59 +04:00
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
const QString enabledByDefault_symbol = QStringLiteral("effect_enabledbydefault_") + name;
|
2011-05-02 00:37:59 +04:00
|
|
|
KLibrary::void_function_ptr enabledByDefault_func = library->resolveFunction(enabledByDefault_symbol.toAscii().data());
|
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
const QString supported_symbol = QStringLiteral("effect_supported_") + name;
|
2007-04-29 21:35:43 +04:00
|
|
|
KLibrary::void_function_ptr supported_func = library->resolveFunction(supported_symbol.toAscii().data());
|
2011-05-02 00:37:59 +04:00
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
const QString create_symbol = QStringLiteral("effect_create_") + name;
|
2007-04-29 21:35:43 +04:00
|
|
|
KLibrary::void_function_ptr create_func = library->resolveFunction(create_symbol.toAscii().data());
|
2011-05-02 00:37:59 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
if (supported_func) {
|
2007-04-29 21:35:43 +04:00
|
|
|
typedef bool (*t_supportedfunc)();
|
|
|
|
t_supportedfunc supported = reinterpret_cast<t_supportedfunc>(supported_func);
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!supported()) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qWarning() << "EffectsHandler::loadEffect : Effect " << name << " is not supported" ;
|
2007-04-29 21:35:43 +04:00
|
|
|
library->unload();
|
2007-07-21 01:13:10 +04:00
|
|
|
return false;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2011-05-02 00:37:59 +04:00
|
|
|
|
|
|
|
if (checkDefault && enabledByDefault_func) {
|
|
|
|
typedef bool (*t_enabledByDefaultfunc)();
|
|
|
|
t_enabledByDefaultfunc enabledByDefault = reinterpret_cast<t_enabledByDefaultfunc>(enabledByDefault_func);
|
|
|
|
|
|
|
|
if (!enabledByDefault()) {
|
|
|
|
library->unload();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!create_func) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qCritical() << "EffectsHandler::loadEffect : effect_create function not found" << endl;
|
2007-04-29 21:35:43 +04:00
|
|
|
library->unload();
|
2007-07-21 01:13:10 +04:00
|
|
|
return false;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2011-05-02 00:37:59 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
typedef Effect*(*t_createfunc)();
|
2007-04-29 21:35:43 +04:00
|
|
|
t_createfunc create = reinterpret_cast<t_createfunc>(create_func);
|
|
|
|
|
2007-07-21 22:30:06 +04:00
|
|
|
// Make sure all depenedencies have been loaded
|
|
|
|
// TODO: detect circular deps
|
2011-01-30 17:34:42 +03:00
|
|
|
KPluginInfo plugininfo(service);
|
2007-07-21 22:30:06 +04:00
|
|
|
QStringList dependencies = plugininfo.dependencies();
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const QString & depName : dependencies) {
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!loadEffect(depName)) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qCritical() << "EffectsHandler::loadEffect : Couldn't load dependencies for effect " << name << endl;
|
2007-07-21 22:30:06 +04:00
|
|
|
library->unload();
|
|
|
|
return false;
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-07-21 22:30:06 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
Effect* e = create();
|
|
|
|
|
2013-07-23 09:02:52 +04:00
|
|
|
effect_order.insert(service->property(QStringLiteral("X-KDE-Ordering")).toInt(), EffectPair(name, e));
|
2007-07-06 16:38:41 +04:00
|
|
|
effectsChanged();
|
2007-04-29 21:35:43 +04:00
|
|
|
effect_libraries[ name ] = library;
|
2007-07-21 01:13:10 +04:00
|
|
|
|
|
|
|
return true;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2012-01-29 20:32:56 +04:00
|
|
|
bool EffectsHandlerImpl::loadScriptedEffect(const QString& name, KService *service)
|
|
|
|
{
|
2012-09-23 09:23:41 +04:00
|
|
|
#ifdef KWIN_BUILD_SCRIPTING
|
2013-08-01 10:04:31 +04:00
|
|
|
const KDesktopFile df(QStandardPaths::GenericDataLocation, QStringLiteral("kde5/services/") + service->entryPath());
|
2013-07-23 09:02:52 +04:00
|
|
|
const QString scriptName = df.desktopGroup().readEntry<QString>(QStringLiteral("X-Plasma-MainScript"), QString());
|
2012-01-29 20:32:56 +04:00
|
|
|
if (scriptName.isEmpty()) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qDebug() << "X-Plasma-MainScript not set";
|
2012-01-29 20:32:56 +04:00
|
|
|
return false;
|
|
|
|
}
|
2013-08-09 16:19:09 +04:00
|
|
|
const QString scriptFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(KWIN_NAME) + QStringLiteral("/effects/") + name + QStringLiteral("/contents/") + scriptName);
|
2012-01-29 20:32:56 +04:00
|
|
|
if (scriptFile.isNull()) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qDebug() << "Could not locate the effect script";
|
2012-01-29 20:32:56 +04:00
|
|
|
return false;
|
|
|
|
}
|
2012-02-01 17:26:54 +04:00
|
|
|
ScriptedEffect *effect = ScriptedEffect::create(name, scriptFile);
|
2012-01-29 20:32:56 +04:00
|
|
|
if (!effect) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qDebug() << "Could not initialize scripted effect: " << name;
|
2012-01-29 20:32:56 +04:00
|
|
|
return false;
|
|
|
|
}
|
2013-07-23 09:02:52 +04:00
|
|
|
effect_order.insert(service->property(QStringLiteral("X-KDE-Ordering")).toInt(), EffectPair(name, effect));
|
2012-01-29 20:32:56 +04:00
|
|
|
effectsChanged();
|
|
|
|
return true;
|
2012-09-23 09:23:41 +04:00
|
|
|
#else
|
|
|
|
Q_UNUSED(name)
|
|
|
|
Q_UNUSED(service)
|
|
|
|
return false;
|
|
|
|
#endif
|
2012-01-29 20:32:56 +04:00
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectsHandlerImpl::unloadEffect(const QString& name)
|
|
|
|
{
|
2012-08-23 20:04:36 +04:00
|
|
|
m_compositor->addRepaintFull();
|
2011-01-30 17:34:42 +03:00
|
|
|
|
|
|
|
for (QMap< int, EffectPair >::iterator it = effect_order.begin(); it != effect_order.end(); ++it) {
|
|
|
|
if (it.value().first == name) {
|
2013-09-02 15:14:39 +04:00
|
|
|
qDebug() << "EffectsHandler::unloadEffect : Unloading Effect : " << name;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (activeFullScreenEffect() == it.value().second) {
|
|
|
|
setActiveFullScreenEffect(0);
|
|
|
|
}
|
2013-04-24 18:51:04 +04:00
|
|
|
stopMouseInterception(it.value().second);
|
2012-12-14 03:09:47 +04:00
|
|
|
// remove support properties for the effect
|
|
|
|
const QList<QByteArray> properties = m_propertiesForEffects.keys();
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const QByteArray &property : properties) {
|
2012-12-14 03:09:47 +04:00
|
|
|
removeSupportProperty(property, it.value().second);
|
|
|
|
}
|
2007-07-06 16:38:41 +04:00
|
|
|
delete it.value().second;
|
|
|
|
effect_order.erase(it);
|
|
|
|
effectsChanged();
|
2012-01-29 20:32:56 +04:00
|
|
|
if (effect_libraries.contains(name)) {
|
|
|
|
effect_libraries[ name ]->unload();
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-02 15:14:39 +04:00
|
|
|
qDebug() << "EffectsHandler::unloadEffect : Effect not loaded : " << name;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectsHandlerImpl::reconfigureEffect(const QString& name)
|
|
|
|
{
|
2013-07-19 13:34:01 +04:00
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it)
|
2011-01-30 17:34:42 +03:00
|
|
|
if ((*it).first == name) {
|
|
|
|
(*it).second->reconfigure(Effect::ReconfigureAll);
|
2008-10-02 13:27:32 +04:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
}
|
2007-05-29 15:42:47 +04:00
|
|
|
|
2012-08-11 13:24:37 +04:00
|
|
|
bool EffectsHandlerImpl::isEffectLoaded(const QString& name) const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2012-08-11 13:24:37 +04:00
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it)
|
2011-01-30 17:34:42 +03:00
|
|
|
if ((*it).first == name)
|
2007-05-29 15:42:47 +04:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-05-29 15:42:47 +04:00
|
|
|
|
2011-11-26 19:15:46 +04:00
|
|
|
void EffectsHandlerImpl::reloadEffect(Effect *effect)
|
|
|
|
{
|
|
|
|
QString effectName;
|
2013-07-19 13:34:01 +04:00
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
|
2011-11-26 19:15:46 +04:00
|
|
|
if ((*it).second == effect) {
|
|
|
|
effectName = (*it).first;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!effectName.isNull()) {
|
|
|
|
unloadEffect(effectName);
|
|
|
|
loadEffect(effectName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-06 16:38:41 +04:00
|
|
|
void EffectsHandlerImpl::effectsChanged()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-07-06 16:38:41 +04:00
|
|
|
loaded_effects.clear();
|
2013-05-04 01:12:53 +04:00
|
|
|
m_activeEffects.clear(); // it's possible to have a reconfigure and a quad rebuild between two paint cycles - bug #308201
|
2013-09-02 15:14:39 +04:00
|
|
|
// qDebug() << "Recreating effects' list:";
|
2013-09-24 16:31:35 +04:00
|
|
|
for (const EffectPair & effect : effect_order) {
|
2013-09-02 15:14:39 +04:00
|
|
|
// qDebug() << effect.first;
|
2011-01-30 17:34:42 +03:00
|
|
|
loaded_effects.append(effect);
|
2007-07-06 16:38:41 +04:00
|
|
|
}
|
2013-07-19 13:46:42 +04:00
|
|
|
m_activeEffects.reserve(loaded_effects.count());
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-07-06 16:38:41 +04:00
|
|
|
|
2011-12-30 02:33:45 +04:00
|
|
|
QStringList EffectsHandlerImpl::activeEffects() const
|
|
|
|
{
|
|
|
|
QStringList ret;
|
|
|
|
for(QVector< KWin::EffectPair >::const_iterator it = loaded_effects.constBegin(),
|
|
|
|
end = loaded_effects.constEnd(); it != end; ++it) {
|
|
|
|
if (it->second->isActive()) {
|
|
|
|
ret << it->first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
EffectFrame* EffectsHandlerImpl::effectFrame(EffectFrameStyle style, bool staticSize, const QPoint& position, Qt::Alignment alignment) const
|
|
|
|
{
|
|
|
|
return new EffectFrameImpl(style, staticSize, position, alignment);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-04-25 19:04:04 +04:00
|
|
|
|
|
|
|
QVariant EffectsHandlerImpl::kwinOption(KWinOption kwopt)
|
|
|
|
{
|
2011-08-10 01:53:46 +04:00
|
|
|
switch (kwopt) {
|
|
|
|
case CloseButtonCorner:
|
2013-04-08 14:31:16 +04:00
|
|
|
return decorationPlugin()->closeButtonCorner();
|
2013-02-22 15:37:12 +04:00
|
|
|
#ifdef KWIN_BUILD_SCREENEDGES
|
2013-01-30 16:36:37 +04:00
|
|
|
case SwitchDesktopOnScreenEdge:
|
|
|
|
return ScreenEdges::self()->isDesktopSwitching();
|
|
|
|
case SwitchDesktopOnScreenEdgeMovingWindows:
|
|
|
|
return ScreenEdges::self()->isDesktopSwitchingMovingClients();
|
2013-02-22 15:37:12 +04:00
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
return QVariant(); // an invalid one
|
2011-04-25 19:04:04 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-11 13:24:37 +04:00
|
|
|
QString EffectsHandlerImpl::supportInformation(const QString &name) const
|
|
|
|
{
|
|
|
|
if (!isEffectLoaded(name)) {
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
|
|
|
|
if ((*it).first == name) {
|
2013-07-23 09:02:52 +04:00
|
|
|
QString support((*it).first + QStringLiteral(":\n"));
|
2012-08-11 13:24:37 +04:00
|
|
|
const QMetaObject *metaOptions = (*it).second->metaObject();
|
|
|
|
for (int i=0; i<metaOptions->propertyCount(); ++i) {
|
|
|
|
const QMetaProperty property = metaOptions->property(i);
|
2013-07-23 09:02:52 +04:00
|
|
|
if (QLatin1String(property.name()) == QLatin1String("objectName")) {
|
2012-08-11 13:24:37 +04:00
|
|
|
continue;
|
|
|
|
}
|
2013-07-23 09:02:52 +04:00
|
|
|
support.append(QString::fromUtf8(property.name()) + QStringLiteral(": ") + (*it).second->property(property.name()).toString() + QStringLiteral("\n"));
|
2012-08-11 13:24:37 +04:00
|
|
|
}
|
|
|
|
return support;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
2012-10-28 01:35:19 +04:00
|
|
|
|
2013-01-30 16:07:59 +04:00
|
|
|
bool EffectsHandlerImpl::isScreenLocked() const
|
|
|
|
{
|
|
|
|
return m_screenLockerWatcher->isLocked();
|
|
|
|
}
|
|
|
|
|
2012-10-28 01:35:19 +04:00
|
|
|
QString EffectsHandlerImpl::debug(const QString& name, const QString& parameter) const
|
|
|
|
{
|
2013-07-23 09:02:52 +04:00
|
|
|
QString internalName = name.startsWith(QStringLiteral("kwin4_effect_")) ? name : QStringLiteral("kwin4_effect_") + name;
|
2012-10-28 01:35:19 +04:00
|
|
|
for (QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it) {
|
|
|
|
if ((*it).first == internalName) {
|
|
|
|
return it->second->debug(parameter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
//****************************************
|
|
|
|
// EffectWindowImpl
|
|
|
|
//****************************************
|
|
|
|
|
2011-12-29 13:31:37 +04:00
|
|
|
EffectWindowImpl::EffectWindowImpl(Toplevel *toplevel)
|
|
|
|
: EffectWindow(toplevel)
|
|
|
|
, toplevel(toplevel)
|
2011-01-30 17:34:42 +03:00
|
|
|
, sw(NULL)
|
|
|
|
{
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
EffectWindowImpl::~EffectWindowImpl()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
QVariant cachedTextureVariant = data(LanczosCacheRole);
|
|
|
|
if (cachedTextureVariant.isValid()) {
|
2010-11-01 13:46:11 +03:00
|
|
|
GLTexture *cachedTexture = static_cast< GLTexture*>(cachedTextureVariant.value<void*>());
|
|
|
|
delete cachedTexture;
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
bool EffectWindowImpl::isPaintingEnabled()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
return sceneWindow()->isPaintingEnabled();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectWindowImpl::enablePainting(int reason)
|
|
|
|
{
|
|
|
|
sceneWindow()->enablePainting(reason);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectWindowImpl::disablePainting(int reason)
|
|
|
|
{
|
|
|
|
sceneWindow()->disablePainting(reason);
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
const EffectWindowGroup* EffectWindowImpl::group() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (Client* c = dynamic_cast< Client* >(toplevel))
|
2007-04-29 21:35:43 +04:00
|
|
|
return c->group()->effectGroup();
|
|
|
|
return NULL; // TODO
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectWindowImpl::refWindow()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (Deleted* d = dynamic_cast< Deleted* >(toplevel))
|
2007-04-29 21:35:43 +04:00
|
|
|
return d->refWindow();
|
|
|
|
abort(); // TODO
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
|
|
|
void EffectWindowImpl::unrefWindow()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (Deleted* d = dynamic_cast< Deleted* >(toplevel))
|
2013-05-31 21:15:51 +04:00
|
|
|
return d->unrefWindow(); // delays deletion in case
|
2007-04-29 21:35:43 +04:00
|
|
|
abort(); // TODO
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectWindowImpl::setWindow(Toplevel* w)
|
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
toplevel = w;
|
2011-12-29 13:31:37 +04:00
|
|
|
setParent(w);
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectWindowImpl::setSceneWindow(Scene::Window* w)
|
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
sw = w;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2007-12-07 21:03:24 +03:00
|
|
|
QRegion EffectWindowImpl::shape() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-12-07 21:03:24 +03:00
|
|
|
return sw ? sw->shape() : geometry();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-12-07 21:03:24 +03:00
|
|
|
|
2010-03-12 19:33:01 +03:00
|
|
|
QRect EffectWindowImpl::decorationInnerRect() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-03-12 19:33:01 +03:00
|
|
|
Client *client = dynamic_cast<Client*>(toplevel);
|
|
|
|
return client ? client->transparentRect() : contentsRect();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-03-12 19:33:01 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QByteArray EffectWindowImpl::readProperty(long atom, long type, int format) const
|
|
|
|
{
|
|
|
|
return readWindowProperty(window()->window(), atom, type, format);
|
|
|
|
}
|
2008-01-02 18:21:33 +03:00
|
|
|
|
2009-06-27 14:21:49 +04:00
|
|
|
void EffectWindowImpl::deleteProperty(long int atom) const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
deleteWindowProperty(window()->window(), atom);
|
|
|
|
}
|
2009-06-27 14:21:49 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindow* EffectWindowImpl::findModal()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (Client* c = dynamic_cast< Client* >(toplevel)) {
|
|
|
|
if (Client* c2 = c->findModal())
|
2007-04-29 21:35:43 +04:00
|
|
|
return c2->effectWindow();
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-06-03 17:08:05 +04:00
|
|
|
template <typename T>
|
|
|
|
EffectWindowList getMainWindows(Toplevel *toplevel)
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2013-06-03 17:08:05 +04:00
|
|
|
T *c = static_cast<T*>(toplevel);
|
|
|
|
EffectWindowList ret;
|
|
|
|
ClientList mainclients = c->mainClients();
|
2013-09-24 16:31:35 +04:00
|
|
|
for (Client * tmp : mainclients)
|
2011-01-30 17:34:42 +03:00
|
|
|
ret.append(tmp->effectWindow());
|
2013-06-03 17:08:05 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
EffectWindowList EffectWindowImpl::mainWindows() const
|
|
|
|
{
|
|
|
|
if (toplevel->isClient()) {
|
|
|
|
return getMainWindows<Client>(toplevel);
|
|
|
|
} else if (toplevel->isDeleted()) {
|
|
|
|
return getMainWindows<Deleted>(toplevel);
|
2007-04-29 21:35:43 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
return EffectWindowList();
|
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
WindowQuadList EffectWindowImpl::buildQuads(bool force) const
|
|
|
|
{
|
|
|
|
return sceneWindow()->buildQuads(force);
|
|
|
|
}
|
2007-08-08 18:42:06 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectWindowImpl::setData(int role, const QVariant &data)
|
|
|
|
{
|
|
|
|
if (!data.isNull())
|
2010-01-03 20:50:38 +03:00
|
|
|
dataMap[ role ] = data;
|
|
|
|
else
|
2011-01-30 17:34:42 +03:00
|
|
|
dataMap.remove(role);
|
|
|
|
}
|
2010-01-03 20:50:38 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
QVariant EffectWindowImpl::data(int role) const
|
|
|
|
{
|
|
|
|
if (!dataMap.contains(role))
|
2010-01-03 20:50:38 +03:00
|
|
|
return QVariant();
|
|
|
|
return dataMap[ role ];
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-01-03 20:50:38 +03:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
EffectWindow* effectWindow(Toplevel* w)
|
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindowImpl* ret = w->effectWindow();
|
|
|
|
return ret;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
EffectWindow* effectWindow(Scene::Window* w)
|
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindowImpl* ret = w->window()->effectWindow();
|
2011-01-30 17:34:42 +03:00
|
|
|
ret->setSceneWindow(w);
|
2007-04-29 21:35:43 +04:00
|
|
|
return ret;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2013-04-24 12:46:34 +04:00
|
|
|
void EffectWindowImpl::elevate(bool elevate)
|
|
|
|
{
|
|
|
|
effects->setElevatedWindow(this, elevate);
|
|
|
|
}
|
|
|
|
|
2012-03-29 17:32:41 +04:00
|
|
|
void EffectWindowImpl::registerThumbnail(AbstractThumbnailItem *item)
|
2011-11-10 17:28:06 +04:00
|
|
|
{
|
2012-03-29 17:46:53 +04:00
|
|
|
if (WindowThumbnailItem *thumb = qobject_cast<WindowThumbnailItem*>(item)) {
|
2012-03-29 17:32:41 +04:00
|
|
|
insertThumbnail(thumb);
|
|
|
|
connect(thumb, SIGNAL(destroyed(QObject*)), SLOT(thumbnailDestroyed(QObject*)));
|
|
|
|
connect(thumb, SIGNAL(wIdChanged(qulonglong)), SLOT(thumbnailTargetChanged()));
|
2012-03-29 22:17:57 +04:00
|
|
|
} else if (DesktopThumbnailItem *desktopThumb = qobject_cast<DesktopThumbnailItem*>(item)) {
|
|
|
|
m_desktopThumbnails.append(desktopThumb);
|
|
|
|
connect(desktopThumb, SIGNAL(destroyed(QObject*)), SLOT(desktopThumbnailDestroyed(QObject*)));
|
2012-03-29 17:32:41 +04:00
|
|
|
}
|
2011-11-10 17:28:06 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectWindowImpl::thumbnailDestroyed(QObject *object)
|
|
|
|
{
|
|
|
|
// we know it is a ThumbnailItem
|
2012-03-29 17:46:53 +04:00
|
|
|
m_thumbnails.remove(static_cast<WindowThumbnailItem*>(object));
|
2011-11-10 17:28:06 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void EffectWindowImpl::thumbnailTargetChanged()
|
|
|
|
{
|
2012-03-29 17:46:53 +04:00
|
|
|
if (WindowThumbnailItem *item = qobject_cast<WindowThumbnailItem*>(sender())) {
|
2011-11-10 17:28:06 +04:00
|
|
|
insertThumbnail(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-29 17:46:53 +04:00
|
|
|
void EffectWindowImpl::insertThumbnail(WindowThumbnailItem *item)
|
2011-11-10 17:28:06 +04:00
|
|
|
{
|
|
|
|
EffectWindow *w = effects->findWindow(item->wId());
|
|
|
|
if (w) {
|
|
|
|
m_thumbnails.insert(item, QWeakPointer<EffectWindowImpl>(static_cast<EffectWindowImpl*>(w)));
|
|
|
|
} else {
|
|
|
|
m_thumbnails.insert(item, QWeakPointer<EffectWindowImpl>());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-29 22:17:57 +04:00
|
|
|
void EffectWindowImpl::desktopThumbnailDestroyed(QObject *object)
|
|
|
|
{
|
|
|
|
// we know it is a DesktopThumbnailItem
|
|
|
|
m_desktopThumbnails.removeAll(static_cast<DesktopThumbnailItem*>(object));
|
|
|
|
}
|
|
|
|
|
2013-05-13 10:17:28 +04:00
|
|
|
void EffectWindowImpl::referencePreviousWindowPixmap()
|
|
|
|
{
|
|
|
|
if (sw) {
|
|
|
|
sw->referencePreviousPixmap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EffectWindowImpl::unreferencePreviousWindowPixmap()
|
|
|
|
{
|
|
|
|
if (sw) {
|
|
|
|
sw->unreferencePreviousPixmap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
//****************************************
|
|
|
|
// EffectWindowGroupImpl
|
|
|
|
//****************************************
|
|
|
|
|
2008-06-02 23:52:02 +04:00
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindowList EffectWindowGroupImpl::members() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2007-04-29 21:35:43 +04:00
|
|
|
EffectWindowList ret;
|
2013-09-24 16:31:35 +04:00
|
|
|
for (Toplevel * c : group->members())
|
2011-01-30 17:34:42 +03:00
|
|
|
ret.append(c->effectWindow());
|
2007-04-29 21:35:43 +04:00
|
|
|
return ret;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2007-04-29 21:35:43 +04:00
|
|
|
|
2010-07-18 20:32:37 +04:00
|
|
|
//****************************************
|
|
|
|
// EffectFrameImpl
|
|
|
|
//****************************************
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
EffectFrameImpl::EffectFrameImpl(EffectFrameStyle style, bool staticSize, QPoint position, Qt::Alignment alignment)
|
|
|
|
: QObject(0)
|
2010-07-18 20:32:37 +04:00
|
|
|
, EffectFrame()
|
2011-01-30 17:34:42 +03:00
|
|
|
, m_style(style)
|
|
|
|
, m_static(staticSize)
|
|
|
|
, m_point(position)
|
|
|
|
, m_alignment(alignment)
|
|
|
|
, m_shader(NULL)
|
2013-07-22 18:10:47 +04:00
|
|
|
, m_theme(new Plasma::Theme(this))
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (m_style == EffectFrameStyled) {
|
2013-07-23 09:02:52 +04:00
|
|
|
m_frame.setImagePath(QStringLiteral("widgets/background"));
|
2011-01-30 17:34:42 +03:00
|
|
|
m_frame.setCacheAllRenderedFrames(true);
|
2013-07-22 18:10:47 +04:00
|
|
|
connect(m_theme, SIGNAL(themeChanged()), this, SLOT(plasmaThemeChanged()));
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2013-07-23 09:02:52 +04:00
|
|
|
m_selection.setImagePath(QStringLiteral("widgets/viewitem"));
|
|
|
|
m_selection.setElementPrefix(QStringLiteral("hover"));
|
2011-04-28 15:41:11 +04:00
|
|
|
m_selection.setCacheAllRenderedFrames(true);
|
|
|
|
m_selection.setEnabledBorders(Plasma::FrameSvg::AllBorders);
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2012-09-20 13:33:32 +04:00
|
|
|
if (effects->isOpenGLCompositing()) {
|
2012-08-26 19:14:23 +04:00
|
|
|
m_sceneFrame = new SceneOpenGL::EffectFrame(this, static_cast<SceneOpenGL*>(Compositor::self()->scene()));
|
2011-01-30 17:34:42 +03:00
|
|
|
} else if (effects->compositingType() == XRenderCompositing) {
|
2011-07-07 21:17:00 +04:00
|
|
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
2011-01-30 17:34:42 +03:00
|
|
|
m_sceneFrame = new SceneXrender::EffectFrame(this);
|
2011-07-07 21:17:00 +04:00
|
|
|
#endif
|
2011-01-30 17:34:42 +03:00
|
|
|
} else {
|
2010-07-18 20:32:37 +04:00
|
|
|
// that should not happen and will definitely crash!
|
|
|
|
m_sceneFrame = NULL;
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
EffectFrameImpl::~EffectFrameImpl()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
delete m_sceneFrame;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
const QFont& EffectFrameImpl::font() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
return m_font;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setFont(const QFont& font)
|
|
|
|
{
|
|
|
|
if (m_font == font) {
|
2010-07-18 20:32:37 +04:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
m_font = font;
|
|
|
|
QRect oldGeom = m_geometry;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!m_text.isEmpty()) {
|
2010-07-18 20:32:37 +04:00
|
|
|
autoResize();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (oldGeom == m_geometry) {
|
|
|
|
// Wasn't updated in autoResize()
|
2010-07-18 20:32:37 +04:00
|
|
|
m_sceneFrame->freeTextFrame();
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
void EffectFrameImpl::free()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
m_sceneFrame->free();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
const QRect& EffectFrameImpl::geometry() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
return m_geometry;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setGeometry(const QRect& geometry, bool force)
|
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
QRect oldGeom = m_geometry;
|
|
|
|
m_geometry = geometry;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (m_geometry == oldGeom && !force) {
|
2010-07-18 20:32:37 +04:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
effects->addRepaint(oldGeom);
|
|
|
|
effects->addRepaint(m_geometry);
|
|
|
|
if (m_geometry.size() == oldGeom.size() && !force) {
|
2010-07-18 20:32:37 +04:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
if (m_style == EffectFrameStyled) {
|
2010-07-18 20:32:37 +04:00
|
|
|
qreal left, top, right, bottom;
|
2011-01-30 17:34:42 +03:00
|
|
|
m_frame.getMargins(left, top, right, bottom); // m_geometry is the inner geometry
|
|
|
|
m_frame.resizeFrame(m_geometry.adjusted(-left, -top, right, bottom).size());
|
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
free();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
const QPixmap& EffectFrameImpl::icon() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
return m_icon;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setIcon(const QPixmap& icon)
|
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
m_icon = icon;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (isCrossFade()) {
|
2010-08-07 18:08:34 +04:00
|
|
|
m_sceneFrame->crossFadeIcon();
|
2010-07-18 20:32:37 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
if (m_iconSize.isEmpty()) { // Set a size if we don't already have one
|
|
|
|
setIconSize(m_icon.size());
|
|
|
|
}
|
|
|
|
m_sceneFrame->freeIconFrame();
|
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
const QSize& EffectFrameImpl::iconSize() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
return m_iconSize;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setIconSize(const QSize& size)
|
|
|
|
{
|
|
|
|
if (m_iconSize == size) {
|
2010-07-18 20:32:37 +04:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
m_iconSize = size;
|
|
|
|
autoResize();
|
2010-07-21 01:11:03 +04:00
|
|
|
m_sceneFrame->freeIconFrame();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
void EffectFrameImpl::plasmaThemeChanged()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
free();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::render(QRegion region, double opacity, double frameOpacity)
|
|
|
|
{
|
|
|
|
if (m_geometry.isEmpty()) {
|
2010-07-18 20:32:37 +04:00
|
|
|
return; // Nothing to display
|
2010-07-24 20:29:16 +04:00
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
m_shader = NULL;
|
|
|
|
effects->paintEffectFrame(this, region, opacity, frameOpacity);
|
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::finalRender(QRegion region, double opacity, double frameOpacity) const
|
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
region = infiniteRegion(); // TODO: Old region doesn't seem to work with OpenGL
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
m_sceneFrame->render(region, opacity, frameOpacity);
|
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
Qt::Alignment EffectFrameImpl::alignment() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
return m_alignment;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2010-12-04 13:01:57 +03:00
|
|
|
|
|
|
|
void
|
2011-01-30 17:34:42 +03:00
|
|
|
EffectFrameImpl::align(QRect &geometry)
|
2010-12-04 13:01:57 +03:00
|
|
|
{
|
2011-01-30 17:34:42 +03:00
|
|
|
if (m_alignment & Qt::AlignLeft)
|
|
|
|
geometry.moveLeft(m_point.x());
|
|
|
|
else if (m_alignment & Qt::AlignRight)
|
|
|
|
geometry.moveLeft(m_point.x() - geometry.width());
|
2010-12-04 13:01:57 +03:00
|
|
|
else
|
2011-01-30 17:34:42 +03:00
|
|
|
geometry.moveLeft(m_point.x() - geometry.width() / 2);
|
|
|
|
if (m_alignment & Qt::AlignTop)
|
|
|
|
geometry.moveTop(m_point.y());
|
|
|
|
else if (m_alignment & Qt::AlignBottom)
|
|
|
|
geometry.moveTop(m_point.y() - geometry.height());
|
2010-12-04 13:01:57 +03:00
|
|
|
else
|
2011-01-30 17:34:42 +03:00
|
|
|
geometry.moveTop(m_point.y() - geometry.height() / 2);
|
2010-12-04 13:01:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setAlignment(Qt::Alignment alignment)
|
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
m_alignment = alignment;
|
2011-01-30 17:34:42 +03:00
|
|
|
align(m_geometry);
|
|
|
|
setGeometry(m_geometry);
|
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setPosition(const QPoint& point)
|
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
m_point = point;
|
2010-12-04 13:01:57 +03:00
|
|
|
QRect geometry = m_geometry; // this is important, setGeometry need call repaint for old & new geometry
|
2011-01-30 17:34:42 +03:00
|
|
|
align(geometry);
|
|
|
|
setGeometry(geometry);
|
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
|
|
|
const QString& EffectFrameImpl::text() const
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
2010-07-18 20:32:37 +04:00
|
|
|
return m_text;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setText(const QString& text)
|
|
|
|
{
|
|
|
|
if (m_text == text) {
|
2010-07-18 20:32:37 +04:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
|
|
|
if (isCrossFade()) {
|
2010-08-07 18:08:34 +04:00
|
|
|
m_sceneFrame->crossFadeText();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
m_text = text;
|
|
|
|
QRect oldGeom = m_geometry;
|
|
|
|
autoResize();
|
2011-01-30 17:34:42 +03:00
|
|
|
if (oldGeom == m_geometry) {
|
|
|
|
// Wasn't updated in autoResize()
|
2010-07-18 20:32:37 +04:00
|
|
|
m_sceneFrame->freeTextFrame();
|
|
|
|
}
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-18 20:32:37 +04:00
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
void EffectFrameImpl::setSelection(const QRect& selection)
|
|
|
|
{
|
|
|
|
if (selection == m_selectionGeometry) {
|
2010-07-27 00:00:04 +04:00
|
|
|
return;
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-27 00:00:04 +04:00
|
|
|
m_selectionGeometry = selection;
|
2011-01-30 17:34:42 +03:00
|
|
|
if (m_selectionGeometry.size() != m_selection.frameSize().toSize()) {
|
|
|
|
m_selection.resizeFrame(m_selectionGeometry.size());
|
|
|
|
}
|
2010-07-27 00:00:04 +04:00
|
|
|
// TODO; optimize to only recreate when resizing
|
|
|
|
m_sceneFrame->freeSelection();
|
2011-01-30 17:34:42 +03:00
|
|
|
}
|
2010-07-27 00:00:04 +04:00
|
|
|
|
2010-07-18 20:32:37 +04:00
|
|
|
void EffectFrameImpl::autoResize()
|
2011-01-30 17:34:42 +03:00
|
|
|
{
|
|
|
|
if (m_static)
|
2010-07-18 20:32:37 +04:00
|
|
|
return; // Not automatically resizing
|
|
|
|
|
|
|
|
QRect geometry;
|
|
|
|
// Set size
|
2011-01-30 17:34:42 +03:00
|
|
|
if (!m_text.isEmpty()) {
|
|
|
|
QFontMetrics metrics(m_font);
|
|
|
|
geometry.setSize(metrics.size(0, m_text));
|
|
|
|
}
|
|
|
|
if (!m_icon.isNull() && !m_iconSize.isEmpty()) {
|
|
|
|
geometry.setLeft(-m_iconSize.width());
|
|
|
|
if (m_iconSize.height() > geometry.height())
|
|
|
|
geometry.setHeight(m_iconSize.height());
|
2010-07-18 20:32:37 +04:00
|
|
|
}
|
|
|
|
|
2011-01-30 17:34:42 +03:00
|
|
|
align(geometry);
|
|
|
|
setGeometry(geometry);
|
|
|
|
}
|
|
|
|
|
2011-02-17 21:35:08 +03:00
|
|
|
QColor EffectFrameImpl::styledTextColor()
|
|
|
|
{
|
2013-07-22 18:10:47 +04:00
|
|
|
return m_theme->color(Plasma::Theme::TextColor);
|
2011-02-17 21:35:08 +03:00
|
|
|
}
|
|
|
|
|
2007-04-29 21:35:43 +04:00
|
|
|
} // namespace
|