044ffb3a4b
Unless the mouse pointer is not next to an electric border kwin calls Outline::hide() on every move/resize event. To avoid unnecessary repaints we now check whether the outline has been visible or not.
202 lines
8.1 KiB
C++
202 lines
8.1 KiB
C++
/********************************************************************
|
|
KWin - the KDE window manager
|
|
This file is part of the KDE project.
|
|
|
|
Copyright (C) 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************/
|
|
|
|
#include "outline.h"
|
|
#include "effects.h"
|
|
#include <QtCore/QRect>
|
|
#include <QtGui/QX11Info>
|
|
#include <QtGui/QPainter>
|
|
#include <X11/Xlib.h>
|
|
|
|
namespace KWin {
|
|
|
|
Outline::Outline()
|
|
: m_initialized(false)
|
|
, m_active(false)
|
|
{
|
|
}
|
|
|
|
Outline::~Outline()
|
|
{
|
|
if (m_initialized) {
|
|
XDestroyWindow(QX11Info::display(), m_leftOutline);
|
|
XDestroyWindow(QX11Info::display(), m_rightOutline);
|
|
XDestroyWindow(QX11Info::display(), m_topOutline);
|
|
XDestroyWindow(QX11Info::display(), m_bottomOutline);
|
|
}
|
|
}
|
|
|
|
void Outline::show()
|
|
{
|
|
m_active = true;
|
|
if (effects && static_cast<EffectsHandlerImpl*>(effects)->provides(Effect::Outline)) {
|
|
static_cast<EffectsHandlerImpl*>(effects)->slotShowOutline(m_outlineGeometry);
|
|
return; // done by effect
|
|
}
|
|
showWithX();
|
|
}
|
|
|
|
void Outline::hide()
|
|
{
|
|
if (!m_active) {
|
|
return;
|
|
}
|
|
m_active = false;
|
|
if (effects && static_cast<EffectsHandlerImpl*>(effects)->provides(Effect::Outline)) {
|
|
static_cast<EffectsHandlerImpl*>(effects)->slotHideOutline();
|
|
return; // done by effect
|
|
}
|
|
hideWithX();
|
|
}
|
|
|
|
void Outline::show(const QRect& outlineGeometry)
|
|
{
|
|
setGeometry(outlineGeometry);
|
|
show();
|
|
}
|
|
|
|
void Outline::setGeometry(const QRect& outlineGeometry)
|
|
{
|
|
m_outlineGeometry = outlineGeometry;
|
|
}
|
|
|
|
QVector< Window > Outline::windowIds() const
|
|
{
|
|
QVector<Window> windows;
|
|
if (m_initialized) {
|
|
windows.reserve(4);
|
|
windows << m_leftOutline << m_topOutline << m_rightOutline << m_bottomOutline;
|
|
}
|
|
return windows;
|
|
}
|
|
|
|
void Outline::showWithX()
|
|
{
|
|
if (!m_initialized) {
|
|
XSetWindowAttributes attr;
|
|
attr.override_redirect = 1;
|
|
m_leftOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
|
|
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
|
|
m_rightOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
|
|
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
|
|
m_topOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
|
|
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
|
|
m_bottomOutline = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(), 0, 0, 1, 1, 0,
|
|
CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr);
|
|
m_initialized = true;
|
|
}
|
|
|
|
int defaultDepth = XDefaultDepth(QX11Info::display(), QX11Info::appScreen());
|
|
|
|
// left/right parts are between top/bottom, they don't reach as far as the corners
|
|
XMoveResizeWindow(QX11Info::display(), m_leftOutline, m_outlineGeometry.x(), m_outlineGeometry.y() + 5, 5, m_outlineGeometry.height() - 10);
|
|
XMoveResizeWindow(QX11Info::display(), m_rightOutline, m_outlineGeometry.x() + m_outlineGeometry.width() - 5, m_outlineGeometry.y() + 5, 5, m_outlineGeometry.height() - 10);
|
|
XMoveResizeWindow(QX11Info::display(), m_topOutline, m_outlineGeometry.x(), m_outlineGeometry.y(), m_outlineGeometry.width(), 5);
|
|
XMoveResizeWindow(QX11Info::display(), m_bottomOutline, m_outlineGeometry.x(), m_outlineGeometry.y() + m_outlineGeometry.height() - 5, m_outlineGeometry.width(), 5);
|
|
{
|
|
Pixmap xpix = XCreatePixmap(display(), rootWindow(), 5,
|
|
m_outlineGeometry.height() - 10, defaultDepth);
|
|
QPixmap pix = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared);
|
|
QPainter p(&pix);
|
|
p.setPen(Qt::white);
|
|
p.drawLine(0, 0, 0, pix.height() - 1);
|
|
p.drawLine(4, 0, 4, pix.height() - 1);
|
|
p.setPen(Qt::gray);
|
|
p.drawLine(1, 0, 1, pix.height() - 1);
|
|
p.drawLine(3, 0, 3, pix.height() - 1);
|
|
p.setPen(Qt::black);
|
|
p.drawLine(2, 0, 2, pix.height() - 1);
|
|
p.end();
|
|
XSetWindowBackgroundPixmap(QX11Info::display(), m_leftOutline, pix.handle());
|
|
XSetWindowBackgroundPixmap(QX11Info::display(), m_rightOutline, pix.handle());
|
|
// According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed.
|
|
XFreePixmap (display(), xpix);
|
|
}
|
|
{
|
|
Pixmap xpix = XCreatePixmap(display(), rootWindow(), m_outlineGeometry.width(),
|
|
5, defaultDepth);
|
|
QPixmap pix = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared);
|
|
QPainter p(&pix);
|
|
p.setPen(Qt::white);
|
|
p.drawLine(0, 0, pix.width() - 1 - 0, 0);
|
|
p.drawLine(4, 4, pix.width() - 1 - 4, 4);
|
|
p.drawLine(0, 0, 0, 4);
|
|
p.drawLine(pix.width() - 1 - 0, 0, pix.width() - 1 - 0, 4);
|
|
p.setPen(Qt::gray);
|
|
p.drawLine(1, 1, pix.width() - 1 - 1, 1);
|
|
p.drawLine(3, 3, pix.width() - 1 - 3, 3);
|
|
p.drawLine(1, 1, 1, 4);
|
|
p.drawLine(3, 3, 3, 4);
|
|
p.drawLine(pix.width() - 1 - 1, 1, pix.width() - 1 - 1, 4);
|
|
p.drawLine(pix.width() - 1 - 3, 3, pix.width() - 1 - 3, 4);
|
|
p.setPen(Qt::black);
|
|
p.drawLine(2, 2, pix.width() - 1 - 2, 2);
|
|
p.drawLine(2, 2, 2, 4);
|
|
p.drawLine(pix.width() - 1 - 2, 2, pix.width() - 1 - 2, 4);
|
|
p.end();
|
|
XSetWindowBackgroundPixmap(QX11Info::display(), m_topOutline, pix.handle());
|
|
// According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed.
|
|
XFreePixmap (display(), xpix);
|
|
}
|
|
{
|
|
Pixmap xpix = XCreatePixmap(display(), rootWindow(), m_outlineGeometry.width(),
|
|
5, defaultDepth);
|
|
QPixmap pix = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared);
|
|
QPainter p(&pix);
|
|
p.setPen(Qt::white);
|
|
p.drawLine(4, 0, pix.width() - 1 - 4, 0);
|
|
p.drawLine(0, 4, pix.width() - 1 - 0, 4);
|
|
p.drawLine(0, 4, 0, 0);
|
|
p.drawLine(pix.width() - 1 - 0, 4, pix.width() - 1 - 0, 0);
|
|
p.setPen(Qt::gray);
|
|
p.drawLine(3, 1, pix.width() - 1 - 3, 1);
|
|
p.drawLine(1, 3, pix.width() - 1 - 1, 3);
|
|
p.drawLine(3, 1, 3, 0);
|
|
p.drawLine(1, 3, 1, 0);
|
|
p.drawLine(pix.width() - 1 - 3, 1, pix.width() - 1 - 3, 0);
|
|
p.drawLine(pix.width() - 1 - 1, 3, pix.width() - 1 - 1, 0);
|
|
p.setPen(Qt::black);
|
|
p.drawLine(2, 2, pix.width() - 1 - 2, 2);
|
|
p.drawLine(2, 0, 2, 2);
|
|
p.drawLine(pix.width() - 1 - 2, 0, pix.width() - 1 - 2, 2);
|
|
p.end();
|
|
XSetWindowBackgroundPixmap(QX11Info::display(), m_bottomOutline, pix.handle());
|
|
// According to the XSetWindowBackgroundPixmap documentation the pixmap can be freed.
|
|
XFreePixmap (display(), xpix);
|
|
}
|
|
XClearWindow(QX11Info::display(), m_leftOutline);
|
|
XClearWindow(QX11Info::display(), m_rightOutline);
|
|
XClearWindow(QX11Info::display(), m_topOutline);
|
|
XClearWindow(QX11Info::display(), m_bottomOutline);
|
|
XMapWindow(QX11Info::display(), m_leftOutline);
|
|
XMapWindow(QX11Info::display(), m_rightOutline);
|
|
XMapWindow(QX11Info::display(), m_topOutline);
|
|
XMapWindow(QX11Info::display(), m_bottomOutline);
|
|
}
|
|
|
|
void Outline::hideWithX()
|
|
{
|
|
XUnmapWindow(QX11Info::display(), m_leftOutline);
|
|
XUnmapWindow(QX11Info::display(), m_rightOutline);
|
|
XUnmapWindow(QX11Info::display(), m_topOutline);
|
|
XUnmapWindow(QX11Info::display(), m_bottomOutline);
|
|
}
|
|
|
|
} // namespace
|