Embedded mode for TabBox
DBus method to embedd the TabBox into another window. It follows the geometry changes and keeps a defined offset to the borders of the parent window. Required for Plasma Active's window strip.icc-effect-5.14.5
parent
b57ef77bf7
commit
5eb5a60cc5
|
@ -39,6 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <kephal/screens.h>
|
#include <kephal/screens.h>
|
||||||
// KWin
|
// KWin
|
||||||
#include "thumbnailitem.h"
|
#include "thumbnailitem.h"
|
||||||
|
#include <kwindowsystem.h>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
@ -104,10 +105,16 @@ DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
|
||||||
, m_currentScreenGeometry()
|
, m_currentScreenGeometry()
|
||||||
, m_frame(new Plasma::FrameSvg(this))
|
, m_frame(new Plasma::FrameSvg(this))
|
||||||
, m_currentLayout()
|
, m_currentLayout()
|
||||||
|
, m_cachedWidth(0)
|
||||||
|
, m_cachedHeight(0)
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_TranslucentBackground);
|
setAttribute(Qt::WA_TranslucentBackground);
|
||||||
setWindowFlags(Qt::X11BypassWindowManagerHint);
|
setWindowFlags(Qt::X11BypassWindowManagerHint);
|
||||||
|
if (tabBox->embedded()) {
|
||||||
|
setResizeMode(QDeclarativeView::SizeRootObjectToView);
|
||||||
|
} else {
|
||||||
setResizeMode(QDeclarativeView::SizeViewToRootObject);
|
setResizeMode(QDeclarativeView::SizeViewToRootObject);
|
||||||
|
}
|
||||||
QPalette pal = palette();
|
QPalette pal = palette();
|
||||||
pal.setColor(backgroundRole(), Qt::transparent);
|
pal.setColor(backgroundRole(), Qt::transparent);
|
||||||
setPalette(pal);
|
setPalette(pal);
|
||||||
|
@ -130,10 +137,14 @@ DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
|
||||||
m_frame->setEnabledBorders(Plasma::FrameSvg::AllBorders);
|
m_frame->setEnabledBorders(Plasma::FrameSvg::AllBorders);
|
||||||
|
|
||||||
connect(tabBox, SIGNAL(configChanged()), SLOT(updateQmlSource()));
|
connect(tabBox, SIGNAL(configChanged()), SLOT(updateQmlSource()));
|
||||||
|
connect(tabBox, SIGNAL(embeddedChanged(bool)), SLOT(slotEmbeddedChanged(bool)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclarativeView::showEvent(QShowEvent *event)
|
void DeclarativeView::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
|
if (tabBox->embedded()) {
|
||||||
|
connect(KWindowSystem::self(), SIGNAL(windowChanged(WId,uint)), SLOT(slotWindowChanged(WId, uint)));
|
||||||
|
}
|
||||||
updateQmlSource();
|
updateQmlSource();
|
||||||
m_currentScreenGeometry = Kephal::ScreenUtils::screenGeometry(tabBox->activeScreen());
|
m_currentScreenGeometry = Kephal::ScreenUtils::screenGeometry(tabBox->activeScreen());
|
||||||
rootObject()->setProperty("screenWidth", m_currentScreenGeometry.width());
|
rootObject()->setProperty("screenWidth", m_currentScreenGeometry.width());
|
||||||
|
@ -154,10 +165,12 @@ void DeclarativeView::showEvent(QShowEvent *event)
|
||||||
void DeclarativeView::resizeEvent(QResizeEvent *event)
|
void DeclarativeView::resizeEvent(QResizeEvent *event)
|
||||||
{
|
{
|
||||||
m_frame->resizeFrame(event->size());
|
m_frame->resizeFrame(event->size());
|
||||||
if (Plasma::Theme::defaultTheme()->windowTranslucencyEnabled()) {
|
if (Plasma::Theme::defaultTheme()->windowTranslucencyEnabled() && !tabBox->embedded()) {
|
||||||
// blur background
|
// blur background
|
||||||
Plasma::WindowEffects::enableBlurBehind(winId(), true, m_frame->mask());
|
Plasma::WindowEffects::enableBlurBehind(winId(), true, m_frame->mask());
|
||||||
Plasma::WindowEffects::overrideShadow(winId(), true);
|
Plasma::WindowEffects::overrideShadow(winId(), true);
|
||||||
|
} else if (tabBox->embedded()) {
|
||||||
|
Plasma::WindowEffects::enableBlurBehind(winId(), false);
|
||||||
} else {
|
} else {
|
||||||
// do not trim to mask with compositing enabled, otherwise shadows are cropped
|
// do not trim to mask with compositing enabled, otherwise shadows are cropped
|
||||||
setMask(m_frame->mask());
|
setMask(m_frame->mask());
|
||||||
|
@ -165,14 +178,52 @@ void DeclarativeView::resizeEvent(QResizeEvent *event)
|
||||||
QDeclarativeView::resizeEvent(event);
|
QDeclarativeView::resizeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeclarativeView::hideEvent(QHideEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::hideEvent(event);
|
||||||
|
if (tabBox->embedded()) {
|
||||||
|
disconnect(KWindowSystem::self(), SIGNAL(windowChanged(WId,uint)), this, SLOT(slotWindowChanged(WId,uint)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DeclarativeView::slotUpdateGeometry()
|
void DeclarativeView::slotUpdateGeometry()
|
||||||
{
|
{
|
||||||
|
const WId embeddedId = tabBox->embedded();
|
||||||
|
if (embeddedId != 0) {
|
||||||
|
const KWindowInfo info = KWindowSystem::windowInfo(embeddedId, NET::WMGeometry);
|
||||||
|
const Qt::Alignment alignment = tabBox->embeddedAlignment();
|
||||||
|
const QPoint offset = tabBox->embeddedOffset();
|
||||||
|
int x = info.geometry().left();
|
||||||
|
int y = info.geometry().top();
|
||||||
|
int width = tabBox->embeddedSize().width();
|
||||||
|
int height = tabBox->embeddedSize().height();
|
||||||
|
if (alignment.testFlag(Qt::AlignLeft) || alignment.testFlag(Qt::AlignHCenter)) {
|
||||||
|
x += offset.x();
|
||||||
|
}
|
||||||
|
if (alignment.testFlag(Qt::AlignRight)) {
|
||||||
|
x = x + info.geometry().width() - offset.x() - width;
|
||||||
|
}
|
||||||
|
if (alignment.testFlag(Qt::AlignHCenter)) {
|
||||||
|
width = info.geometry().width() - 2 * offset.x();
|
||||||
|
}
|
||||||
|
if (alignment.testFlag(Qt::AlignTop) || alignment.testFlag(Qt::AlignVCenter)) {
|
||||||
|
y += offset.y();
|
||||||
|
}
|
||||||
|
if (alignment.testFlag(Qt::AlignBottom)) {
|
||||||
|
y = y + info.geometry().height() - offset.y() - height;
|
||||||
|
}
|
||||||
|
if (alignment.testFlag(Qt::AlignVCenter)) {
|
||||||
|
height = info.geometry().height() - 2 * offset.y();
|
||||||
|
}
|
||||||
|
setGeometry(QRect(x, y, width, height));
|
||||||
|
} else {
|
||||||
const int width = rootObject()->property("width").toInt();
|
const int width = rootObject()->property("width").toInt();
|
||||||
const int height = rootObject()->property("height").toInt();
|
const int height = rootObject()->property("height").toInt();
|
||||||
setGeometry(m_currentScreenGeometry.x() + static_cast<qreal>(m_currentScreenGeometry.width()) * 0.5 - static_cast<qreal>(width) * 0.5,
|
setGeometry(m_currentScreenGeometry.x() + static_cast<qreal>(m_currentScreenGeometry.width()) * 0.5 - static_cast<qreal>(width) * 0.5,
|
||||||
m_currentScreenGeometry.y() + static_cast<qreal>(m_currentScreenGeometry.height()) * 0.5 - static_cast<qreal>(height) * 0.5,
|
m_currentScreenGeometry.y() + static_cast<qreal>(m_currentScreenGeometry.height()) * 0.5 - static_cast<qreal>(height) * 0.5,
|
||||||
width, height);
|
width, height);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DeclarativeView::setCurrentIndex(const QModelIndex &index)
|
void DeclarativeView::setCurrentIndex(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
|
@ -201,9 +252,9 @@ void DeclarativeView::currentIndexChanged(int row)
|
||||||
tabBox->setCurrentIndex(m_model->index(row, 0));
|
tabBox->setCurrentIndex(m_model->index(row, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclarativeView::updateQmlSource()
|
void DeclarativeView::updateQmlSource(bool force)
|
||||||
{
|
{
|
||||||
if (tabBox->config().layoutName() == m_currentLayout) {
|
if (!force && tabBox->config().layoutName() == m_currentLayout) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_currentLayout = tabBox->config().layoutName();
|
m_currentLayout = tabBox->config().layoutName();
|
||||||
|
@ -215,5 +266,32 @@ void DeclarativeView::updateQmlSource()
|
||||||
rootObject()->setProperty("source", QUrl(file));
|
rootObject()->setProperty("source", QUrl(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeclarativeView::slotEmbeddedChanged(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
// cache the width
|
||||||
|
setResizeMode(QDeclarativeView::SizeRootObjectToView);
|
||||||
|
m_cachedWidth = rootObject()->property("width").toInt();
|
||||||
|
m_cachedHeight = rootObject()->property("height").toInt();
|
||||||
|
} else {
|
||||||
|
setResizeMode(QDeclarativeView::SizeViewToRootObject);
|
||||||
|
if (m_cachedWidth != 0 && m_cachedHeight != 0) {
|
||||||
|
rootObject()->setProperty("width", m_cachedWidth);
|
||||||
|
rootObject()->setProperty("height", m_cachedHeight);
|
||||||
|
}
|
||||||
|
updateQmlSource(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeclarativeView::slotWindowChanged(WId wId, unsigned int properties)
|
||||||
|
{
|
||||||
|
if (wId != tabBox->embedded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (properties & NET::WMGeometry) {
|
||||||
|
slotUpdateGeometry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace TabBox
|
} // namespace TabBox
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
|
@ -58,11 +58,16 @@ public:
|
||||||
void setCurrentIndex(const QModelIndex &index);
|
void setCurrentIndex(const QModelIndex &index);
|
||||||
QModelIndex indexAt(const QPoint &pos) const;
|
QModelIndex indexAt(const QPoint &pos) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void hideEvent(QHideEvent *event);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void slotUpdateGeometry();
|
void slotUpdateGeometry();
|
||||||
|
void slotEmbeddedChanged(bool enabled);
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void updateQmlSource();
|
void updateQmlSource(bool force = false);
|
||||||
void currentIndexChanged(int row);
|
void currentIndexChanged(int row);
|
||||||
|
void slotWindowChanged(WId wId, unsigned int properties);
|
||||||
private:
|
private:
|
||||||
QAbstractItemModel *m_model;
|
QAbstractItemModel *m_model;
|
||||||
QRect m_currentScreenGeometry;
|
QRect m_currentScreenGeometry;
|
||||||
|
@ -71,6 +76,8 @@ private:
|
||||||
*/
|
*/
|
||||||
Plasma::FrameSvg* m_frame;
|
Plasma::FrameSvg* m_frame;
|
||||||
QString m_currentLayout;
|
QString m_currentLayout;
|
||||||
|
int m_cachedWidth;
|
||||||
|
int m_cachedHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TabBox
|
} // namespace TabBox
|
||||||
|
|
|
@ -968,7 +968,23 @@ void TabBox::open(bool modal)
|
||||||
} else {
|
} else {
|
||||||
m_tabGrab = false;
|
m_tabGrab = false;
|
||||||
}
|
}
|
||||||
|
m_noModifierGrab = !modal;
|
||||||
|
setMode(TabBoxWindowsMode);
|
||||||
|
reset();
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBox::openEmbedded(qulonglong wid, QPoint offset, QSize size, int horizontalAlignment, int verticalAlignment)
|
||||||
|
{
|
||||||
|
if (isDisplayed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_tabGrab = false;
|
||||||
m_noModifierGrab = true;
|
m_noModifierGrab = true;
|
||||||
|
tabBox->setEmbedded(static_cast<WId>(wid));
|
||||||
|
tabBox->setEmbeddedOffset(offset);
|
||||||
|
tabBox->setEmbeddedSize(size);
|
||||||
|
tabBox->setEmbeddedAlignment(static_cast<Qt::AlignmentFlag>(horizontalAlignment) | static_cast<Qt::AlignmentFlag>(verticalAlignment));
|
||||||
setMode(TabBoxWindowsMode);
|
setMode(TabBoxWindowsMode);
|
||||||
reset();
|
reset();
|
||||||
show();
|
show();
|
||||||
|
@ -980,6 +996,7 @@ bool TabBox::startKDEWalkThroughWindows(TabBoxMode mode)
|
||||||
return false;
|
return false;
|
||||||
m_tabGrab = true;
|
m_tabGrab = true;
|
||||||
m_noModifierGrab = false;
|
m_noModifierGrab = false;
|
||||||
|
tabBox->resetEmbedded();
|
||||||
modalActionsSwitch(false);
|
modalActionsSwitch(false);
|
||||||
setMode(mode);
|
setMode(mode);
|
||||||
reset();
|
reset();
|
||||||
|
|
|
@ -175,6 +175,22 @@ public slots:
|
||||||
* mode or whether the TabBox is controlled externally (e.g. through an effect).
|
* mode or whether the TabBox is controlled externally (e.g. through an effect).
|
||||||
**/
|
**/
|
||||||
Q_SCRIPTABLE void open(bool modal = true);
|
Q_SCRIPTABLE void open(bool modal = true);
|
||||||
|
/**
|
||||||
|
* Opens the TabBox view embedded on a different window. This implies non-modal mode.
|
||||||
|
* The geometry of the TabBox is determined by offset, size and the alignment flags.
|
||||||
|
* If the alignment flags are set to center the view scales with the container. That is if
|
||||||
|
* the window where the TabBox is embedded onto resizes, the TabBox resizes, too.
|
||||||
|
* The alignment in combination with the offset determines to what border the TabBox is snapped.
|
||||||
|
* E.g. if horizontal alignment is right the offset is interpreted as the offset between right
|
||||||
|
* corner of TabBox view and the container view. When the container changes its geometry this
|
||||||
|
* offset is kept. So the offset on the left side would increase.
|
||||||
|
* @param wid The window Id the TabBox should be embedded onto
|
||||||
|
* @param offset The offset to one of the size borders
|
||||||
|
* @param size The size of the TabBox. To use the same size as the container, set alignment to center
|
||||||
|
* @param horizontalAlignment Either Qt::AlignLeft, Qt::AlignHCenter or Qt::AlignRight
|
||||||
|
* @param verticalAlignment Either Qt::AlignTop, Qt::AlignVCenter or Qt::AlignBottom
|
||||||
|
**/
|
||||||
|
Q_SCRIPTABLE void openEmbedded(qulonglong wid, QPoint offset, QSize size, int horizontalAlignment, int verticalAlignment);
|
||||||
Q_SCRIPTABLE void close(bool abort = false);
|
Q_SCRIPTABLE void close(bool abort = false);
|
||||||
void slotWalkThroughDesktops();
|
void slotWalkThroughDesktops();
|
||||||
void slotWalkBackThroughDesktops();
|
void slotWalkBackThroughDesktops();
|
||||||
|
|
|
@ -89,11 +89,18 @@ public:
|
||||||
bool isShown;
|
bool isShown;
|
||||||
QMap< QString, ItemLayoutConfig > tabBoxLayouts;
|
QMap< QString, ItemLayoutConfig > tabBoxLayouts;
|
||||||
TabBoxClient *lastRaisedClient, *lastRaisedClientSucc;
|
TabBoxClient *lastRaisedClient, *lastRaisedClientSucc;
|
||||||
|
WId m_embedded;
|
||||||
|
QPoint m_embeddedOffset;
|
||||||
|
QSize m_embeddedSize;
|
||||||
|
Qt::Alignment m_embeddedAlignment;
|
||||||
};
|
};
|
||||||
|
|
||||||
TabBoxHandlerPrivate::TabBoxHandlerPrivate(TabBoxHandler *q)
|
TabBoxHandlerPrivate::TabBoxHandlerPrivate(TabBoxHandler *q)
|
||||||
: view(NULL)
|
: view(NULL)
|
||||||
, m_declarativeView(NULL)
|
, m_declarativeView(NULL)
|
||||||
|
, m_embedded(0)
|
||||||
|
, m_embeddedOffset(QPoint(0, 0))
|
||||||
|
, m_embeddedSize(QSize(0, 0))
|
||||||
{
|
{
|
||||||
this->q = q;
|
this->q = q;
|
||||||
isShown = false;
|
isShown = false;
|
||||||
|
@ -698,6 +705,58 @@ QWidget* TabBoxHandler::tabBoxView() const
|
||||||
return d->view;
|
return d->view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WId TabBoxHandler::embedded() const
|
||||||
|
{
|
||||||
|
return d->m_embedded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBoxHandler::setEmbedded(WId wid)
|
||||||
|
{
|
||||||
|
d->m_embedded = wid;
|
||||||
|
emit embeddedChanged(wid != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBoxHandler::setEmbeddedOffset(const QPoint &offset)
|
||||||
|
{
|
||||||
|
d->m_embeddedOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBoxHandler::setEmbeddedSize(const QSize &size)
|
||||||
|
{
|
||||||
|
d->m_embeddedSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QPoint &TabBoxHandler::embeddedOffset() const
|
||||||
|
{
|
||||||
|
return d->m_embeddedOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSize &TabBoxHandler::embeddedSize() const
|
||||||
|
{
|
||||||
|
return d->m_embeddedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::Alignment TabBoxHandler::embeddedAlignment() const
|
||||||
|
{
|
||||||
|
return d->m_embeddedAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBoxHandler::setEmbeddedAlignment(Qt::Alignment alignment)
|
||||||
|
{
|
||||||
|
d->m_embeddedAlignment = alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBoxHandler::resetEmbedded()
|
||||||
|
{
|
||||||
|
if (d->m_embedded == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d->m_embedded = 0;
|
||||||
|
d->m_embeddedOffset = QPoint(0, 0);
|
||||||
|
d->m_embeddedSize = QSize(0, 0);
|
||||||
|
emit embeddedChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
TabBoxHandler* tabBox = 0;
|
TabBoxHandler* tabBox = 0;
|
||||||
|
|
||||||
TabBoxClient::TabBoxClient()
|
TabBoxClient::TabBoxClient()
|
||||||
|
|
|
@ -315,6 +315,16 @@ public:
|
||||||
*/
|
*/
|
||||||
QModelIndex first() const;
|
QModelIndex first() const;
|
||||||
|
|
||||||
|
void setEmbedded(WId wid);
|
||||||
|
WId embedded() const;
|
||||||
|
void setEmbeddedOffset(const QPoint &offset);
|
||||||
|
const QPoint &embeddedOffset() const;
|
||||||
|
void setEmbeddedSize(const QSize &size);
|
||||||
|
const QSize &embeddedSize() const;
|
||||||
|
void setEmbeddedAlignment(Qt::Alignment alignment);
|
||||||
|
Qt::Alignment embeddedAlignment() const;
|
||||||
|
void resetEmbedded();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The tabBoxView Widget
|
* @return The tabBoxView Widget
|
||||||
*/
|
*/
|
||||||
|
@ -348,6 +358,7 @@ signals:
|
||||||
*/
|
*/
|
||||||
void configChanged();
|
void configChanged();
|
||||||
void ready();
|
void ready();
|
||||||
|
void embeddedChanged(bool enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class TabBoxHandlerPrivate;
|
friend class TabBoxHandlerPrivate;
|
||||||
|
|
Loading…
Reference in New Issue