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>
|
||||
// KWin
|
||||
#include "thumbnailitem.h"
|
||||
#include <kwindowsystem.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -104,10 +105,16 @@ DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
|
|||
, m_currentScreenGeometry()
|
||||
, m_frame(new Plasma::FrameSvg(this))
|
||||
, m_currentLayout()
|
||||
, m_cachedWidth(0)
|
||||
, m_cachedHeight(0)
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setWindowFlags(Qt::X11BypassWindowManagerHint);
|
||||
setResizeMode(QDeclarativeView::SizeViewToRootObject);
|
||||
if (tabBox->embedded()) {
|
||||
setResizeMode(QDeclarativeView::SizeRootObjectToView);
|
||||
} else {
|
||||
setResizeMode(QDeclarativeView::SizeViewToRootObject);
|
||||
}
|
||||
QPalette pal = palette();
|
||||
pal.setColor(backgroundRole(), Qt::transparent);
|
||||
setPalette(pal);
|
||||
|
@ -130,10 +137,14 @@ DeclarativeView::DeclarativeView(QAbstractItemModel *model, QWidget *parent)
|
|||
m_frame->setEnabledBorders(Plasma::FrameSvg::AllBorders);
|
||||
|
||||
connect(tabBox, SIGNAL(configChanged()), SLOT(updateQmlSource()));
|
||||
connect(tabBox, SIGNAL(embeddedChanged(bool)), SLOT(slotEmbeddedChanged(bool)));
|
||||
}
|
||||
|
||||
void DeclarativeView::showEvent(QShowEvent *event)
|
||||
{
|
||||
if (tabBox->embedded()) {
|
||||
connect(KWindowSystem::self(), SIGNAL(windowChanged(WId,uint)), SLOT(slotWindowChanged(WId, uint)));
|
||||
}
|
||||
updateQmlSource();
|
||||
m_currentScreenGeometry = Kephal::ScreenUtils::screenGeometry(tabBox->activeScreen());
|
||||
rootObject()->setProperty("screenWidth", m_currentScreenGeometry.width());
|
||||
|
@ -154,10 +165,12 @@ void DeclarativeView::showEvent(QShowEvent *event)
|
|||
void DeclarativeView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
m_frame->resizeFrame(event->size());
|
||||
if (Plasma::Theme::defaultTheme()->windowTranslucencyEnabled()) {
|
||||
if (Plasma::Theme::defaultTheme()->windowTranslucencyEnabled() && !tabBox->embedded()) {
|
||||
// blur background
|
||||
Plasma::WindowEffects::enableBlurBehind(winId(), true, m_frame->mask());
|
||||
Plasma::WindowEffects::overrideShadow(winId(), true);
|
||||
} else if (tabBox->embedded()) {
|
||||
Plasma::WindowEffects::enableBlurBehind(winId(), false);
|
||||
} else {
|
||||
// do not trim to mask with compositing enabled, otherwise shadows are cropped
|
||||
setMask(m_frame->mask());
|
||||
|
@ -165,13 +178,51 @@ void DeclarativeView::resizeEvent(QResizeEvent *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()
|
||||
{
|
||||
const int width = rootObject()->property("width").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,
|
||||
m_currentScreenGeometry.y() + static_cast<qreal>(m_currentScreenGeometry.height()) * 0.5 - static_cast<qreal>(height) * 0.5,
|
||||
width, height);
|
||||
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 height = rootObject()->property("height").toInt();
|
||||
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,
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void DeclarativeView::setCurrentIndex(const QModelIndex &index)
|
||||
|
@ -201,9 +252,9 @@ void DeclarativeView::currentIndexChanged(int row)
|
|||
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;
|
||||
}
|
||||
m_currentLayout = tabBox->config().layoutName();
|
||||
|
@ -215,5 +266,32 @@ void DeclarativeView::updateQmlSource()
|
|||
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 KWin
|
||||
|
|
|
@ -58,11 +58,16 @@ public:
|
|||
void setCurrentIndex(const QModelIndex &index);
|
||||
QModelIndex indexAt(const QPoint &pos) const;
|
||||
|
||||
protected:
|
||||
virtual void hideEvent(QHideEvent *event);
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotUpdateGeometry();
|
||||
void slotEmbeddedChanged(bool enabled);
|
||||
private Q_SLOTS:
|
||||
void updateQmlSource();
|
||||
void updateQmlSource(bool force = false);
|
||||
void currentIndexChanged(int row);
|
||||
void slotWindowChanged(WId wId, unsigned int properties);
|
||||
private:
|
||||
QAbstractItemModel *m_model;
|
||||
QRect m_currentScreenGeometry;
|
||||
|
@ -71,6 +76,8 @@ private:
|
|||
*/
|
||||
Plasma::FrameSvg* m_frame;
|
||||
QString m_currentLayout;
|
||||
int m_cachedWidth;
|
||||
int m_cachedHeight;
|
||||
};
|
||||
|
||||
} // namespace TabBox
|
||||
|
|
|
@ -968,7 +968,23 @@ void TabBox::open(bool modal)
|
|||
} else {
|
||||
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;
|
||||
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);
|
||||
reset();
|
||||
show();
|
||||
|
@ -980,6 +996,7 @@ bool TabBox::startKDEWalkThroughWindows(TabBoxMode mode)
|
|||
return false;
|
||||
m_tabGrab = true;
|
||||
m_noModifierGrab = false;
|
||||
tabBox->resetEmbedded();
|
||||
modalActionsSwitch(false);
|
||||
setMode(mode);
|
||||
reset();
|
||||
|
|
|
@ -175,6 +175,22 @@ public slots:
|
|||
* mode or whether the TabBox is controlled externally (e.g. through an effect).
|
||||
**/
|
||||
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);
|
||||
void slotWalkThroughDesktops();
|
||||
void slotWalkBackThroughDesktops();
|
||||
|
|
|
@ -89,11 +89,18 @@ public:
|
|||
bool isShown;
|
||||
QMap< QString, ItemLayoutConfig > tabBoxLayouts;
|
||||
TabBoxClient *lastRaisedClient, *lastRaisedClientSucc;
|
||||
WId m_embedded;
|
||||
QPoint m_embeddedOffset;
|
||||
QSize m_embeddedSize;
|
||||
Qt::Alignment m_embeddedAlignment;
|
||||
};
|
||||
|
||||
TabBoxHandlerPrivate::TabBoxHandlerPrivate(TabBoxHandler *q)
|
||||
: view(NULL)
|
||||
, m_declarativeView(NULL)
|
||||
, m_embedded(0)
|
||||
, m_embeddedOffset(QPoint(0, 0))
|
||||
, m_embeddedSize(QSize(0, 0))
|
||||
{
|
||||
this->q = q;
|
||||
isShown = false;
|
||||
|
@ -698,6 +705,58 @@ QWidget* TabBoxHandler::tabBoxView() const
|
|||
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;
|
||||
|
||||
TabBoxClient::TabBoxClient()
|
||||
|
|
|
@ -315,6 +315,16 @@ public:
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -348,6 +358,7 @@ signals:
|
|||
*/
|
||||
void configChanged();
|
||||
void ready();
|
||||
void embeddedChanged(bool enabled);
|
||||
|
||||
private:
|
||||
friend class TabBoxHandlerPrivate;
|
||||
|
|
Loading…
Reference in New Issue