Merge branch 'kwin/tabbox-window-strip' into integration
This commit is contained in:
commit
6f9f736973
20 changed files with 575 additions and 29 deletions
|
@ -18,7 +18,6 @@ endif(${KDE_PLATFORM_PROFILE} STREQUAL "Desktop")
|
||||||
if(KWIN_PLASMA_ACTIVE)
|
if(KWIN_PLASMA_ACTIVE)
|
||||||
set(KWIN_BUILD_DECORATIONS OFF)
|
set(KWIN_BUILD_DECORATIONS OFF)
|
||||||
set(KWIN_BUILD_KCMS OFF)
|
set(KWIN_BUILD_KCMS OFF)
|
||||||
set(KWIN_BUILD_TABBOX OFF)
|
|
||||||
set(KWIN_BUILD_TILING OFF)
|
set(KWIN_BUILD_TILING OFF)
|
||||||
set(KWIN_BUILD_DESKTOPCHANGEOSD OFF)
|
set(KWIN_BUILD_DESKTOPCHANGEOSD OFF)
|
||||||
set(KWIN_BUILD_SCREENEDGES OFF)
|
set(KWIN_BUILD_SCREENEDGES OFF)
|
||||||
|
@ -257,6 +256,7 @@ install( FILES
|
||||||
tabbox/qml/text.qml
|
tabbox/qml/text.qml
|
||||||
tabbox/qml/thumbnails.qml
|
tabbox/qml/thumbnails.qml
|
||||||
tabbox/qml/IconTabBox.qml
|
tabbox/qml/IconTabBox.qml
|
||||||
|
tabbox/qml/window_strip.qml
|
||||||
DESTINATION ${DATA_INSTALL_DIR}/kwin/tabbox )
|
DESTINATION ${DATA_INSTALL_DIR}/kwin/tabbox )
|
||||||
|
|
||||||
kde4_install_icons( ${ICON_INSTALL_DIR} )
|
kde4_install_icons( ${ICON_INSTALL_DIR} )
|
||||||
|
|
|
@ -126,6 +126,9 @@ Atoms::Atoms()
|
||||||
atoms[n] = &kde_net_wm_tab_group;
|
atoms[n] = &kde_net_wm_tab_group;
|
||||||
names[n++] = (char*) "_KDE_NET_WM_TAB_GROUP";
|
names[n++] = (char*) "_KDE_NET_WM_TAB_GROUP";
|
||||||
|
|
||||||
|
atoms[n] = &kde_first_in_window_list;
|
||||||
|
names[n++] = (char*) "_KDE_FIRST_IN_WINDOWLIST";
|
||||||
|
|
||||||
assert(n <= max);
|
assert(n <= max);
|
||||||
|
|
||||||
XInternAtoms(display(), names, n, false, atoms_return);
|
XInternAtoms(display(), names, n, false, atoms_return);
|
||||||
|
|
1
atoms.h
1
atoms.h
|
@ -64,6 +64,7 @@ public:
|
||||||
Atom kde_net_wm_shadow;
|
Atom kde_net_wm_shadow;
|
||||||
Atom net_wm_opaque_region;
|
Atom net_wm_opaque_region;
|
||||||
Atom kde_net_wm_tab_group;
|
Atom kde_net_wm_tab_group;
|
||||||
|
Atom kde_first_in_window_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
19
client.cpp
19
client.cpp
|
@ -129,6 +129,7 @@ Client::Client(Workspace* ws)
|
||||||
, demandAttentionKNotifyTimer(NULL)
|
, demandAttentionKNotifyTimer(NULL)
|
||||||
, m_responsibleForDecoPixmap(false)
|
, m_responsibleForDecoPixmap(false)
|
||||||
, paintRedirector(0)
|
, paintRedirector(0)
|
||||||
|
, m_firstInTabBox(false)
|
||||||
, electricMaximizing(false)
|
, electricMaximizing(false)
|
||||||
, activitiesDefined(false)
|
, activitiesDefined(false)
|
||||||
, needsSessionInteract(false)
|
, needsSessionInteract(false)
|
||||||
|
@ -2408,6 +2409,24 @@ QRect Client::decorationRect() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::updateFirstInTabBox()
|
||||||
|
{
|
||||||
|
// TODO: move into KWindowInfo
|
||||||
|
Atom type;
|
||||||
|
int format, status;
|
||||||
|
unsigned long nitems = 0;
|
||||||
|
unsigned long extra = 0;
|
||||||
|
unsigned char *data = 0;
|
||||||
|
status = XGetWindowProperty(display(), window(), atoms->kde_first_in_window_list, 0, 1, false, atoms->kde_first_in_window_list, &type, &format, &nitems, &extra, &data);
|
||||||
|
if (status == Success && format == 32 && nitems == 1) {
|
||||||
|
setFirstInTabBox(true);
|
||||||
|
} else {
|
||||||
|
setFirstInTabBox(false);
|
||||||
|
}
|
||||||
|
if (data)
|
||||||
|
XFree(data);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#include "client.moc"
|
#include "client.moc"
|
||||||
|
|
8
client.h
8
client.h
|
@ -426,6 +426,13 @@ public:
|
||||||
TabBox::TabBoxClientImpl* tabBoxClient() const {
|
TabBox::TabBoxClientImpl* tabBoxClient() const {
|
||||||
return m_tabBoxClient;
|
return m_tabBoxClient;
|
||||||
}
|
}
|
||||||
|
bool isFirstInTabBox() const {
|
||||||
|
return m_firstInTabBox;
|
||||||
|
}
|
||||||
|
void setFirstInTabBox(bool enable) {
|
||||||
|
m_firstInTabBox = enable;
|
||||||
|
}
|
||||||
|
void updateFirstInTabBox();
|
||||||
|
|
||||||
//sets whether the client should be treated as a SessionInteract window
|
//sets whether the client should be treated as a SessionInteract window
|
||||||
void setSessionInteract(bool needed);
|
void setSessionInteract(bool needed);
|
||||||
|
@ -719,6 +726,7 @@ private:
|
||||||
bool m_responsibleForDecoPixmap;
|
bool m_responsibleForDecoPixmap;
|
||||||
PaintRedirector* paintRedirector;
|
PaintRedirector* paintRedirector;
|
||||||
TabBox::TabBoxClientImpl* m_tabBoxClient;
|
TabBox::TabBoxClientImpl* m_tabBoxClient;
|
||||||
|
bool m_firstInTabBox;
|
||||||
|
|
||||||
bool electricMaximizing;
|
bool electricMaximizing;
|
||||||
QuickTileMode electricMode;
|
QuickTileMode electricMode;
|
||||||
|
|
|
@ -857,6 +857,8 @@ void Client::propertyNotifyEvent(XPropertyEvent* e)
|
||||||
checkActivities();
|
checkActivities();
|
||||||
else if (e->atom == atoms->kde_net_wm_block_compositing)
|
else if (e->atom == atoms->kde_net_wm_block_compositing)
|
||||||
updateCompositeBlocking(true);
|
updateCompositeBlocking(true);
|
||||||
|
else if (e->atom == atoms->kde_first_in_window_list)
|
||||||
|
updateFirstInTabBox();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,7 @@ bool Client::manage(Window w, bool isMapped)
|
||||||
|
|
||||||
original_skip_taskbar = skip_taskbar = (info->state() & NET::SkipTaskbar) != 0;
|
original_skip_taskbar = skip_taskbar = (info->state() & NET::SkipTaskbar) != 0;
|
||||||
skip_pager = (info->state() & NET::SkipPager) != 0;
|
skip_pager = (info->state() & NET::SkipPager) != 0;
|
||||||
|
updateFirstInTabBox();
|
||||||
|
|
||||||
setupCompositing();
|
setupCompositing();
|
||||||
|
|
||||||
|
|
|
@ -419,8 +419,8 @@ void Scene::paintWindow(Window* w, int mask, QRegion region, WindowQuadList quad
|
||||||
} else {
|
} else {
|
||||||
thumbMask |= PAINT_WINDOW_TRANSLUCENT;
|
thumbMask |= PAINT_WINDOW_TRANSLUCENT;
|
||||||
}
|
}
|
||||||
if (x < wImpl->x() || x + size.width() > wImpl->x() + wImpl->width() ||
|
if (item->isClip() && (x < wImpl->x() || x + size.width() > wImpl->x() + wImpl->width() ||
|
||||||
y < wImpl->y() || y + size.height() > wImpl->y() + wImpl->height()) {
|
y < wImpl->y() || y + size.height() > wImpl->y() + wImpl->height())) {
|
||||||
// don't render windows outside the containing window.
|
// don't render windows outside the containing window.
|
||||||
// TODO: improve by spliting out the window quads which do not fit
|
// TODO: improve by spliting out the window quads which do not fit
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -43,6 +43,7 @@ ClientModel::ClientModel(QObject* parent)
|
||||||
roles[DesktopNameRole] = "desktopName";
|
roles[DesktopNameRole] = "desktopName";
|
||||||
roles[MinimizedRole] = "minimized";
|
roles[MinimizedRole] = "minimized";
|
||||||
roles[WIdRole] = "windowId";
|
roles[WIdRole] = "windowId";
|
||||||
|
roles[CloseableRole] = "closeable";
|
||||||
setRoleNames(roles);
|
setRoleNames(roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +81,8 @@ QVariant ClientModel::data(const QModelIndex& index, int role) const
|
||||||
return qulonglong(m_clientList[ clientIndex ]->window());
|
return qulonglong(m_clientList[ clientIndex ]->window());
|
||||||
case MinimizedRole:
|
case MinimizedRole:
|
||||||
return m_clientList[ clientIndex ]->isMinimized();
|
return m_clientList[ clientIndex ]->isMinimized();
|
||||||
|
case CloseableRole:
|
||||||
|
return m_clientList[ clientIndex ]->isCloseable();
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
@ -172,6 +175,7 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
start = m_clientList.first();
|
start = m_clientList.first();
|
||||||
|
|
||||||
m_clientList.clear();
|
m_clientList.clear();
|
||||||
|
QList<TabBoxClient*> stickyClients;
|
||||||
|
|
||||||
switch(tabBox->config().clientSwitchingMode()) {
|
switch(tabBox->config().clientSwitchingMode()) {
|
||||||
case TabBoxConfig::FocusChainSwitching: {
|
case TabBoxConfig::FocusChainSwitching: {
|
||||||
|
@ -187,6 +191,9 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
m_clientList.prepend(add);
|
m_clientList.prepend(add);
|
||||||
} else
|
} else
|
||||||
m_clientList += add;
|
m_clientList += add;
|
||||||
|
if (add->isFirstInTabBox()) {
|
||||||
|
stickyClients << add;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c = tabBox->nextClientFocusChain(c);
|
c = tabBox->nextClientFocusChain(c);
|
||||||
|
|
||||||
|
@ -211,6 +218,9 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
m_clientList.prepend(add);
|
m_clientList.prepend(add);
|
||||||
} else
|
} else
|
||||||
m_clientList += add;
|
m_clientList += add;
|
||||||
|
if (add->isFirstInTabBox()) {
|
||||||
|
stickyClients << add;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (index >= stacking.size() - 1) {
|
if (index >= stacking.size() - 1) {
|
||||||
c = NULL;
|
c = NULL;
|
||||||
|
@ -224,6 +234,10 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
foreach (TabBoxClient *c, stickyClients) {
|
||||||
|
m_clientList.removeAll(c);
|
||||||
|
m_clientList.prepend(c);
|
||||||
|
}
|
||||||
if (tabBox->config().isShowDesktop()) {
|
if (tabBox->config().isShowDesktop()) {
|
||||||
TabBoxClient* desktopClient = tabBox->desktopClient();
|
TabBoxClient* desktopClient = tabBox->desktopClient();
|
||||||
if (desktopClient)
|
if (desktopClient)
|
||||||
|
@ -232,5 +246,24 @@ void ClientModel::createClientList(int desktop, bool partialReset)
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientModel::close(int i)
|
||||||
|
{
|
||||||
|
QModelIndex ind = index(i, 0);
|
||||||
|
if (!ind.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_clientList.at(i)->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientModel::activate(int i)
|
||||||
|
{
|
||||||
|
QModelIndex ind = index(i, 0);
|
||||||
|
if (!ind.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tabBox->setCurrentIndex(ind);
|
||||||
|
tabBox->activateAndClose();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Tabbox
|
} // namespace Tabbox
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace TabBox
|
||||||
class ClientModel
|
class ClientModel
|
||||||
: public QAbstractItemModel
|
: public QAbstractItemModel
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
ClientRole = Qt::UserRole, ///< The TabBoxClient
|
ClientRole = Qt::UserRole, ///< The TabBoxClient
|
||||||
|
@ -54,7 +55,8 @@ public:
|
||||||
IconRole = Qt::UserRole + 3, // TODO: to be removed
|
IconRole = Qt::UserRole + 3, // TODO: to be removed
|
||||||
EmptyRole = Qt::UserRole + 4, ///< Indicates if the model contains TabBoxClients
|
EmptyRole = Qt::UserRole + 4, ///< Indicates if the model contains TabBoxClients
|
||||||
WIdRole = Qt::UserRole + 5, ///< The window ID of TabBoxClient
|
WIdRole = Qt::UserRole + 5, ///< The window ID of TabBoxClient
|
||||||
MinimizedRole = Qt::UserRole + 6 ///< TabBoxClient is minimized
|
MinimizedRole = Qt::UserRole + 6, ///< TabBoxClient is minimized
|
||||||
|
CloseableRole = Qt::UserRole + 7 ///< TabBoxClient can be closed
|
||||||
};
|
};
|
||||||
ClientModel(QObject* parent = 0);
|
ClientModel(QObject* parent = 0);
|
||||||
~ClientModel();
|
~ClientModel();
|
||||||
|
@ -94,6 +96,14 @@ public:
|
||||||
return m_clientList;
|
return m_clientList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void close(int index);
|
||||||
|
/**
|
||||||
|
* Activates the client at @p index and closes the TabBox.
|
||||||
|
* @param index The row index
|
||||||
|
**/
|
||||||
|
void activate(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TabBoxClientList m_clientList;
|
TabBoxClientList m_clientList;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,6 +27,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <QtDeclarative/QDeclarativeEngine>
|
#include <QtDeclarative/QDeclarativeEngine>
|
||||||
#include <QtGui/QGraphicsObject>
|
#include <QtGui/QGraphicsObject>
|
||||||
#include <QtGui/QResizeEvent>
|
#include <QtGui/QResizeEvent>
|
||||||
|
#include <QX11Info>
|
||||||
|
|
||||||
// include KDE
|
// include KDE
|
||||||
#include <KDE/KDebug>
|
#include <KDE/KDebug>
|
||||||
#include <KDE/KIconEffect>
|
#include <KDE/KIconEffect>
|
||||||
|
@ -39,6 +41,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 +107,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);
|
||||||
setResizeMode(QDeclarativeView::SizeViewToRootObject);
|
if (tabBox->embedded()) {
|
||||||
|
setResizeMode(QDeclarativeView::SizeRootObjectToView);
|
||||||
|
} else {
|
||||||
|
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 +139,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 +167,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,13 +180,76 @@ 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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeclarativeView::x11Event(XEvent *e)
|
||||||
|
{
|
||||||
|
if (tabBox->embedded() &&
|
||||||
|
(e->type == ButtonPress || e->type == ButtonRelease || e->type == MotionNotify)) {
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
memcpy(&ev, e, sizeof(ev));
|
||||||
|
if (e->type == ButtonPress || e->type == ButtonRelease) {
|
||||||
|
ev.xbutton.x += m_relativePos.x();
|
||||||
|
ev.xbutton.y += m_relativePos.y();
|
||||||
|
ev.xbutton.window = tabBox->embedded();
|
||||||
|
} else if (e->type == MotionNotify) {
|
||||||
|
ev.xmotion.x += m_relativePos.x();
|
||||||
|
ev.xmotion.y += m_relativePos.y();
|
||||||
|
ev.xmotion.window = tabBox->embedded();
|
||||||
|
}
|
||||||
|
|
||||||
|
XSendEvent( QX11Info::display(), tabBox->embedded(), False, NoEventMask, &ev );
|
||||||
|
}
|
||||||
|
return QDeclarativeView::x11Event(e);
|
||||||
|
}
|
||||||
|
|
||||||
void DeclarativeView::slotUpdateGeometry()
|
void DeclarativeView::slotUpdateGeometry()
|
||||||
{
|
{
|
||||||
const int width = rootObject()->property("width").toInt();
|
const WId embeddedId = tabBox->embedded();
|
||||||
const int height = rootObject()->property("height").toInt();
|
if (embeddedId != 0) {
|
||||||
setGeometry(m_currentScreenGeometry.x() + static_cast<qreal>(m_currentScreenGeometry.width()) * 0.5 - static_cast<qreal>(width) * 0.5,
|
const KWindowInfo info = KWindowSystem::windowInfo(embeddedId, NET::WMGeometry);
|
||||||
m_currentScreenGeometry.y() + static_cast<qreal>(m_currentScreenGeometry.height()) * 0.5 - static_cast<qreal>(height) * 0.5,
|
const Qt::Alignment alignment = tabBox->embeddedAlignment();
|
||||||
width, height);
|
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));
|
||||||
|
|
||||||
|
m_relativePos = QPoint(info.geometry().x(), info.geometry().x());
|
||||||
|
} 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);
|
||||||
|
m_relativePos = pos();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclarativeView::setCurrentIndex(const QModelIndex &index)
|
void DeclarativeView::setCurrentIndex(const QModelIndex &index)
|
||||||
|
@ -201,9 +279,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 +293,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,17 @@ 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);
|
||||||
|
virtual bool x11Event(XEvent *e);
|
||||||
|
|
||||||
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 +77,10 @@ private:
|
||||||
*/
|
*/
|
||||||
Plasma::FrameSvg* m_frame;
|
Plasma::FrameSvg* m_frame;
|
||||||
QString m_currentLayout;
|
QString m_currentLayout;
|
||||||
|
int m_cachedWidth;
|
||||||
|
int m_cachedHeight;
|
||||||
|
//relative position to the embedding window
|
||||||
|
QPoint m_relativePos;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TabBox
|
} // namespace TabBox
|
||||||
|
|
145
tabbox/qml/window_strip.qml
Normal file
145
tabbox/qml/window_strip.qml
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/********************************************************************
|
||||||
|
KWin - the KDE window manager
|
||||||
|
This file is part of the KDE project.
|
||||||
|
|
||||||
|
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
|
||||||
|
Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
*********************************************************************/
|
||||||
|
import QtQuick 1.0
|
||||||
|
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||||
|
import org.kde.plasma.mobilecomponents 0.1 as MobileComponents
|
||||||
|
import org.kde.qtextracomponents 0.1
|
||||||
|
import org.kde.kwin 0.1 as KWin
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: thumbnailTabBox
|
||||||
|
property int screenWidth
|
||||||
|
property bool canStretchX: false
|
||||||
|
property bool canStretchY: false
|
||||||
|
width: screenWidth
|
||||||
|
height: 150
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
|
||||||
|
function setModel(model) {
|
||||||
|
thumbnailListView.model = model;
|
||||||
|
}
|
||||||
|
// just to get the margin sizes
|
||||||
|
PlasmaCore.FrameSvgItem {
|
||||||
|
id: hoverItem
|
||||||
|
imagePath: "widgets/viewitem"
|
||||||
|
prefix: "hover"
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.Theme {
|
||||||
|
id: theme
|
||||||
|
}
|
||||||
|
PlasmaCore.Svg {
|
||||||
|
id: iconsSvg
|
||||||
|
imagePath: "widgets/configuration-icons"
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
/**
|
||||||
|
* Called from C++ to get the index at a mouse pos.
|
||||||
|
**/
|
||||||
|
function indexAtMousePos(pos) {
|
||||||
|
return thumbnailListView.indexAt(pos.x, pos.y);
|
||||||
|
}
|
||||||
|
signal currentIndexChanged(int index)
|
||||||
|
id: thumbnailListView
|
||||||
|
objectName: "listView"
|
||||||
|
orientation: ListView.Horizontal
|
||||||
|
height: parent.height
|
||||||
|
spacing: 10
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
delegate: Item {
|
||||||
|
id: delegateItem
|
||||||
|
width: thumbnailListView.height * 1.6 + 48
|
||||||
|
height: thumbnailListView.height
|
||||||
|
KWin.ThumbnailItem {
|
||||||
|
id: thumbnailItem
|
||||||
|
wId: windowId
|
||||||
|
width: parent.width - closeButtonContainer.width - 20
|
||||||
|
height: thumbnailListView.height - 40
|
||||||
|
clip: false
|
||||||
|
anchors.centerIn: parent
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
thumbnailListView.currentIndex = index;
|
||||||
|
thumbnailListView.currentIndexChanged(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlasmaComponents.Label {
|
||||||
|
id: windowTitle
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
anchors.topMargin: 4
|
||||||
|
|
||||||
|
text: caption
|
||||||
|
elide: Text.ElideRight
|
||||||
|
color: theme.textColor
|
||||||
|
width: parent.width - 40
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
PlasmaCore.FrameSvgItem {
|
||||||
|
id: closeButtonContainer
|
||||||
|
imagePath: "widgets/button"
|
||||||
|
prefix: "shadow"
|
||||||
|
width: closeButton.width + margins.left + margins.right
|
||||||
|
height: closeButton.height + margins.top + margins.bottom
|
||||||
|
visible: closeable
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
right: parent.right
|
||||||
|
topMargin: 32
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.FrameSvgItem {
|
||||||
|
id: closeButton
|
||||||
|
imagePath: "widgets/button"
|
||||||
|
prefix: "normal"
|
||||||
|
//a bit more left margin
|
||||||
|
width: closeButtonSvg.width + margins.left + margins.right + 16
|
||||||
|
height: closeButtonSvg.height + margins.top + margins.bottom
|
||||||
|
x: parent.margins.left
|
||||||
|
y: parent.margins.top
|
||||||
|
|
||||||
|
MobileComponents.ActionButton {
|
||||||
|
id: closeButtonSvg
|
||||||
|
svg: iconsSvg
|
||||||
|
iconSize: 22
|
||||||
|
backgroundVisible: false
|
||||||
|
elementId: "close"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: parent.margins.right
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: thumbnailListView.model.close(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
// Qt
|
// Qt
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
|
#include <QtDBus/QDBusConnection>
|
||||||
// KDE
|
// KDE
|
||||||
#include <KActionCollection>
|
#include <KActionCollection>
|
||||||
#include <KConfig>
|
#include <KConfig>
|
||||||
|
@ -213,6 +214,10 @@ QVector< Window > TabBoxHandlerImpl::outlineWindowIds() const
|
||||||
return Workspace::self()->outline()->windowIds();
|
return Workspace::self()->outline()->windowIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabBoxHandlerImpl::activateAndClose()
|
||||||
|
{
|
||||||
|
m_tabBox->accept();
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
* TabBoxClientImpl
|
* TabBoxClientImpl
|
||||||
|
@ -270,6 +275,20 @@ int TabBoxClientImpl::height() const
|
||||||
return m_client->height();
|
return m_client->height();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TabBoxClientImpl::isCloseable() const
|
||||||
|
{
|
||||||
|
return m_client->isCloseable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBoxClientImpl::close()
|
||||||
|
{
|
||||||
|
m_client->closeWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TabBoxClientImpl::isFirstInTabBox() const
|
||||||
|
{
|
||||||
|
return m_client->isFirstInTabBox();
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
* TabBox
|
* TabBox
|
||||||
|
@ -279,6 +298,7 @@ TabBox::TabBox(QObject *parent)
|
||||||
, m_displayRefcount(0)
|
, m_displayRefcount(0)
|
||||||
, m_desktopGrab(false)
|
, m_desktopGrab(false)
|
||||||
, m_tabGrab(false)
|
, m_tabGrab(false)
|
||||||
|
, m_noModifierGrab(false)
|
||||||
, m_forcedGlobalMouseGrab(false)
|
, m_forcedGlobalMouseGrab(false)
|
||||||
, m_ready(false)
|
, m_ready(false)
|
||||||
{
|
{
|
||||||
|
@ -310,14 +330,17 @@ TabBox::TabBox(QObject *parent)
|
||||||
m_desktopListConfig.setLayout(TabBoxConfig::VerticalLayout);
|
m_desktopListConfig.setLayout(TabBoxConfig::VerticalLayout);
|
||||||
m_tabBox = new TabBoxHandlerImpl(this);
|
m_tabBox = new TabBoxHandlerImpl(this);
|
||||||
connect(m_tabBox, SIGNAL(ready()), SLOT(handlerReady()));
|
connect(m_tabBox, SIGNAL(ready()), SLOT(handlerReady()));
|
||||||
|
connect(m_tabBox, SIGNAL(selectedIndexChanged()), SIGNAL(itemSelected()));
|
||||||
|
|
||||||
m_tabBoxMode = TabBoxDesktopMode; // init variables
|
m_tabBoxMode = TabBoxDesktopMode; // init variables
|
||||||
connect(&m_delayedShowTimer, SIGNAL(timeout()), this, SLOT(show()));
|
connect(&m_delayedShowTimer, SIGNAL(timeout()), this, SLOT(show()));
|
||||||
connect(Workspace::self(), SIGNAL(configChanged()), this, SLOT(reconfigure()));
|
connect(Workspace::self(), SIGNAL(configChanged()), this, SLOT(reconfigure()));
|
||||||
|
QDBusConnection::sessionBus().registerObject("/TabBox", this, QDBusConnection::ExportScriptableContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
TabBox::~TabBox()
|
TabBox::~TabBox()
|
||||||
{
|
{
|
||||||
|
QDBusConnection::sessionBus().unregisterObject("/TabBox");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabBox::handlerReady()
|
void TabBox::handlerReady()
|
||||||
|
@ -659,6 +682,11 @@ void TabBox::grabbedKeyEvent(QKeyEvent* event)
|
||||||
// tabbox has been replaced, check effects
|
// tabbox has been replaced, check effects
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (m_noModifierGrab) {
|
||||||
|
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return || event->key() == Qt::Key_Space) {
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
setCurrentIndex(m_tabBox->grabbedKeyEvent(event));
|
setCurrentIndex(m_tabBox->grabbedKeyEvent(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,11 +941,48 @@ void TabBox::modalActionsSwitch(bool enabled)
|
||||||
action->setEnabled(enabled);
|
action->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabBox::open(bool modal)
|
||||||
|
{
|
||||||
|
if (isDisplayed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (modal) {
|
||||||
|
if (!establishTabBoxGrab()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_tabGrab = true;
|
||||||
|
} 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();
|
||||||
|
}
|
||||||
|
|
||||||
bool TabBox::startKDEWalkThroughWindows(TabBoxMode mode)
|
bool TabBox::startKDEWalkThroughWindows(TabBoxMode mode)
|
||||||
{
|
{
|
||||||
if (!establishTabBoxGrab())
|
if (!establishTabBoxGrab())
|
||||||
return false;
|
return false;
|
||||||
m_tabGrab = true;
|
m_tabGrab = true;
|
||||||
|
m_noModifierGrab = false;
|
||||||
|
tabBox->resetEmbedded();
|
||||||
modalActionsSwitch(false);
|
modalActionsSwitch(false);
|
||||||
setMode(mode);
|
setMode(mode);
|
||||||
reset();
|
reset();
|
||||||
|
@ -929,6 +994,7 @@ bool TabBox::startWalkThroughDesktops(TabBoxMode mode)
|
||||||
if (!establishTabBoxGrab())
|
if (!establishTabBoxGrab())
|
||||||
return false;
|
return false;
|
||||||
m_desktopGrab = true;
|
m_desktopGrab = true;
|
||||||
|
m_noModifierGrab = false;
|
||||||
modalActionsSwitch(false);
|
modalActionsSwitch(false);
|
||||||
setMode(mode);
|
setMode(mode);
|
||||||
reset();
|
reset();
|
||||||
|
@ -1091,11 +1157,32 @@ void TabBox::keyPress(int keyQt)
|
||||||
|
|
||||||
void TabBox::close(bool abort)
|
void TabBox::close(bool abort)
|
||||||
{
|
{
|
||||||
removeTabBoxGrab();
|
if (isGrabbed()) {
|
||||||
|
removeTabBoxGrab();
|
||||||
|
}
|
||||||
hide(abort);
|
hide(abort);
|
||||||
modalActionsSwitch(true);
|
modalActionsSwitch(true);
|
||||||
m_tabGrab = false;
|
m_tabGrab = false;
|
||||||
m_desktopGrab = false;
|
m_desktopGrab = false;
|
||||||
|
m_noModifierGrab = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBox::accept()
|
||||||
|
{
|
||||||
|
Client* c = currentClient();
|
||||||
|
close();
|
||||||
|
if (c) {
|
||||||
|
Workspace::self()->activateClient(c);
|
||||||
|
if (c->isShade() && options->shadeHover)
|
||||||
|
c->setShade(ShadeActivated);
|
||||||
|
if (c->isDesktop())
|
||||||
|
Workspace::self()->setShowingDesktop(!Workspace::self()->showingDesktop());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabBox::reject()
|
||||||
|
{
|
||||||
|
close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1103,6 +1190,9 @@ void TabBox::close(bool abort)
|
||||||
*/
|
*/
|
||||||
void TabBox::keyRelease(const XKeyEvent& ev)
|
void TabBox::keyRelease(const XKeyEvent& ev)
|
||||||
{
|
{
|
||||||
|
if (m_noModifierGrab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
unsigned int mk = ev.state &
|
unsigned int mk = ev.state &
|
||||||
(KKeyServer::modXShift() |
|
(KKeyServer::modXShift() |
|
||||||
KKeyServer::modXCtrl() |
|
KKeyServer::modXCtrl() |
|
||||||
|
@ -1136,16 +1226,8 @@ void TabBox::keyRelease(const XKeyEvent& ev)
|
||||||
return;
|
return;
|
||||||
if (m_tabGrab) {
|
if (m_tabGrab) {
|
||||||
bool old_control_grab = m_desktopGrab;
|
bool old_control_grab = m_desktopGrab;
|
||||||
Client* c = currentClient();
|
accept();
|
||||||
close();
|
|
||||||
m_desktopGrab = old_control_grab;
|
m_desktopGrab = old_control_grab;
|
||||||
if (c) {
|
|
||||||
Workspace::self()->activateClient(c);
|
|
||||||
if (c->isShade() && options->shadeHover)
|
|
||||||
c->setShade(ShadeActivated);
|
|
||||||
if (c->isDesktop())
|
|
||||||
Workspace::self()->setShowingDesktop(!Workspace::self()->showingDesktop());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (m_desktopGrab) {
|
if (m_desktopGrab) {
|
||||||
bool old_tab_grab = m_tabGrab;
|
bool old_tab_grab = m_tabGrab;
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
virtual void hideOutline();
|
virtual void hideOutline();
|
||||||
virtual void showOutline(const QRect &outline);
|
virtual void showOutline(const QRect &outline);
|
||||||
virtual QVector< Window > outlineWindowIds() const;
|
virtual QVector< Window > outlineWindowIds() const;
|
||||||
|
virtual void activateAndClose();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TabBox* m_tabBox;
|
TabBox* m_tabBox;
|
||||||
|
@ -80,6 +81,9 @@ public:
|
||||||
virtual int y() const;
|
virtual int y() const;
|
||||||
virtual int width() const;
|
virtual int width() const;
|
||||||
virtual int height() const;
|
virtual int height() const;
|
||||||
|
virtual bool isCloseable() const;
|
||||||
|
virtual void close();
|
||||||
|
virtual bool isFirstInTabBox() const;
|
||||||
|
|
||||||
Client* client() const {
|
Client* client() const {
|
||||||
return m_client;
|
return m_client;
|
||||||
|
@ -95,6 +99,7 @@ private:
|
||||||
class TabBox : public QObject
|
class TabBox : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_CLASSINFO("D-Bus Interface", "org.kde.kwin")
|
||||||
public:
|
public:
|
||||||
TabBox(QObject *parent = NULL);
|
TabBox(QObject *parent = NULL);
|
||||||
~TabBox();
|
~TabBox();
|
||||||
|
@ -160,12 +165,36 @@ public:
|
||||||
int previousDesktopFocusChain(int iDesktop) const;
|
int previousDesktopFocusChain(int iDesktop) const;
|
||||||
int nextDesktopStatic(int iDesktop) const;
|
int nextDesktopStatic(int iDesktop) const;
|
||||||
int previousDesktopStatic(int iDesktop) const;
|
int previousDesktopStatic(int iDesktop) const;
|
||||||
void close(bool abort = false);
|
|
||||||
void keyPress(int key);
|
void keyPress(int key);
|
||||||
void keyRelease(const XKeyEvent& ev);
|
void keyRelease(const XKeyEvent& ev);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void show();
|
void show();
|
||||||
|
/**
|
||||||
|
* Only for DBus Interface to start primary KDE Walk through windows.
|
||||||
|
* @param modal Whether the TabBox should grab keyboard and mouse, that is go into modal
|
||||||
|
* 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);
|
||||||
|
Q_SCRIPTABLE void accept();
|
||||||
|
Q_SCRIPTABLE void reject();
|
||||||
void slotWalkThroughDesktops();
|
void slotWalkThroughDesktops();
|
||||||
void slotWalkBackThroughDesktops();
|
void slotWalkBackThroughDesktops();
|
||||||
void slotWalkThroughDesktopList();
|
void slotWalkThroughDesktopList();
|
||||||
|
@ -190,7 +219,8 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void tabBoxAdded(int);
|
void tabBoxAdded(int);
|
||||||
void tabBoxClosed();
|
Q_SCRIPTABLE void tabBoxClosed();
|
||||||
|
Q_SCRIPTABLE void itemSelected();
|
||||||
void tabBoxUpdated();
|
void tabBoxUpdated();
|
||||||
void tabBoxKeyEvent(QKeyEvent*);
|
void tabBoxKeyEvent(QKeyEvent*);
|
||||||
|
|
||||||
|
@ -235,6 +265,8 @@ private:
|
||||||
bool m_isShown;
|
bool m_isShown;
|
||||||
bool m_desktopGrab;
|
bool m_desktopGrab;
|
||||||
bool m_tabGrab;
|
bool m_tabGrab;
|
||||||
|
// true if tabbox is in modal mode which does not require holding a modifier
|
||||||
|
bool m_noModifierGrab;
|
||||||
KShortcut m_cutWalkThroughDesktops, m_cutWalkThroughDesktopsReverse;
|
KShortcut m_cutWalkThroughDesktops, m_cutWalkThroughDesktopsReverse;
|
||||||
KShortcut m_cutWalkThroughDesktopList, m_cutWalkThroughDesktopListReverse;
|
KShortcut m_cutWalkThroughDesktopList, m_cutWalkThroughDesktopListReverse;
|
||||||
KShortcut m_cutWalkThroughWindows, m_cutWalkThroughWindowsReverse;
|
KShortcut m_cutWalkThroughWindows, m_cutWalkThroughWindowsReverse;
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -552,6 +559,7 @@ void TabBoxHandler::setCurrentIndex(const QModelIndex& index)
|
||||||
d->updateHighlightWindows();
|
d->updateHighlightWindows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
emit selectedIndexChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QModelIndex& TabBoxHandler::currentIndex() const
|
const QModelIndex& TabBoxHandler::currentIndex() const
|
||||||
|
@ -586,11 +594,13 @@ QModelIndex TabBoxHandler::grabbedKeyEvent(QKeyEvent* event) const
|
||||||
if (column >= model->columnCount())
|
if (column >= model->columnCount())
|
||||||
column = 0;
|
column = 0;
|
||||||
break;
|
break;
|
||||||
|
case Qt::Key_Backtab:
|
||||||
case Qt::Key_Up:
|
case Qt::Key_Up:
|
||||||
row--;
|
row--;
|
||||||
if (row < 0)
|
if (row < 0)
|
||||||
row = model->rowCount() - 1;
|
row = model->rowCount() - 1;
|
||||||
break;
|
break;
|
||||||
|
case Qt::Key_Tab:
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Down:
|
||||||
row++;
|
row++;
|
||||||
if (row >= model->rowCount())
|
if (row >= model->rowCount())
|
||||||
|
@ -696,6 +706,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()
|
||||||
|
|
|
@ -173,6 +173,10 @@ public:
|
||||||
* @return The first desktop window in the stacking order.
|
* @return The first desktop window in the stacking order.
|
||||||
*/
|
*/
|
||||||
virtual TabBoxClient* desktopClient() const = 0;
|
virtual TabBoxClient* desktopClient() const = 0;
|
||||||
|
/**
|
||||||
|
* Activates the currently selected client and closes the TabBox.
|
||||||
|
**/
|
||||||
|
virtual void activateAndClose() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The currently used TabBoxConfig
|
* @return The currently used TabBoxConfig
|
||||||
|
@ -311,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
|
||||||
*/
|
*/
|
||||||
|
@ -344,6 +358,8 @@ signals:
|
||||||
*/
|
*/
|
||||||
void configChanged();
|
void configChanged();
|
||||||
void ready();
|
void ready();
|
||||||
|
void embeddedChanged(bool enabled);
|
||||||
|
void selectedIndexChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class TabBoxHandlerPrivate;
|
friend class TabBoxHandlerPrivate;
|
||||||
|
@ -384,6 +400,9 @@ public:
|
||||||
virtual int y() const = 0;
|
virtual int y() const = 0;
|
||||||
virtual int width() const = 0;
|
virtual int width() const = 0;
|
||||||
virtual int height() const = 0;
|
virtual int height() const = 0;
|
||||||
|
virtual bool isCloseable() const = 0;
|
||||||
|
virtual void close() = 0;
|
||||||
|
virtual bool isFirstInTabBox() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace KWin
|
||||||
ThumbnailItem::ThumbnailItem(QDeclarativeItem* parent)
|
ThumbnailItem::ThumbnailItem(QDeclarativeItem* parent)
|
||||||
: QDeclarativeItem(parent)
|
: QDeclarativeItem(parent)
|
||||||
, m_wId(0)
|
, m_wId(0)
|
||||||
|
, m_clip(true)
|
||||||
, m_parent(QWeakPointer<EffectWindowImpl>())
|
, m_parent(QWeakPointer<EffectWindowImpl>())
|
||||||
{
|
{
|
||||||
setFlags(flags() & ~QGraphicsItem::ItemHasNoContents);
|
setFlags(flags() & ~QGraphicsItem::ItemHasNoContents);
|
||||||
|
@ -81,6 +82,12 @@ void ThumbnailItem::setWId(qulonglong wId)
|
||||||
emit wIdChanged(wId);
|
emit wIdChanged(wId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThumbnailItem::setClip(bool clip)
|
||||||
|
{
|
||||||
|
m_clip = clip;
|
||||||
|
emit clipChanged(clip);
|
||||||
|
}
|
||||||
|
|
||||||
void ThumbnailItem::effectWindowAdded()
|
void ThumbnailItem::effectWindowAdded()
|
||||||
{
|
{
|
||||||
// the window might be added before the EffectWindow is created
|
// the window might be added before the EffectWindow is created
|
||||||
|
|
|
@ -34,6 +34,7 @@ class ThumbnailItem : public QDeclarativeItem
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(qulonglong wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
|
Q_PROPERTY(qulonglong wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
|
||||||
|
Q_PROPERTY(bool clip READ isClip WRITE setClip NOTIFY clipChanged SCRIPTABLE true)
|
||||||
public:
|
public:
|
||||||
ThumbnailItem(QDeclarativeItem *parent = 0);
|
ThumbnailItem(QDeclarativeItem *parent = 0);
|
||||||
virtual ~ThumbnailItem();
|
virtual ~ThumbnailItem();
|
||||||
|
@ -42,15 +43,21 @@ public:
|
||||||
return m_wId;
|
return m_wId;
|
||||||
}
|
}
|
||||||
void setWId(qulonglong wId);
|
void setWId(qulonglong wId);
|
||||||
|
bool isClip() const {
|
||||||
|
return m_clip;
|
||||||
|
}
|
||||||
|
void setClip(bool clip);
|
||||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void wIdChanged(qulonglong wid);
|
void wIdChanged(qulonglong wid);
|
||||||
|
void clipChanged(bool clipped);
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void init();
|
void init();
|
||||||
void effectWindowAdded();
|
void effectWindowAdded();
|
||||||
private:
|
private:
|
||||||
void findParentEffectWindow();
|
void findParentEffectWindow();
|
||||||
qulonglong m_wId;
|
qulonglong m_wId;
|
||||||
|
bool m_clip;
|
||||||
QWeakPointer<EffectWindowImpl> m_parent;
|
QWeakPointer<EffectWindowImpl> m_parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -638,7 +638,7 @@ void Workspace::addClient(Client* c, allowed_t)
|
||||||
updateToolWindows(true);
|
updateToolWindows(true);
|
||||||
checkNonExistentClients();
|
checkNonExistentClients();
|
||||||
#ifdef KWIN_BUILD_TABBOX
|
#ifdef KWIN_BUILD_TABBOX
|
||||||
if (tabBox()->isGrabbed())
|
if (tabBox()->isDisplayed())
|
||||||
tab_box->reset(true);
|
tab_box->reset(true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -672,7 +672,7 @@ void Workspace::removeClient(Client* c, allowed_t)
|
||||||
Notify::raise(Notify::Delete);
|
Notify::raise(Notify::Delete);
|
||||||
|
|
||||||
#ifdef KWIN_BUILD_TABBOX
|
#ifdef KWIN_BUILD_TABBOX
|
||||||
if (tabBox()->isGrabbed() && tabBox()->currentClient() == c)
|
if (tabBox()->isDisplayed() && tabBox()->currentClient() == c)
|
||||||
tab_box->nextPrev(true);
|
tab_box->nextPrev(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -708,7 +708,7 @@ void Workspace::removeClient(Client* c, allowed_t)
|
||||||
updateCompositeBlocking();
|
updateCompositeBlocking();
|
||||||
|
|
||||||
#ifdef KWIN_BUILD_TABBOX
|
#ifdef KWIN_BUILD_TABBOX
|
||||||
if (tabBox()->isGrabbed())
|
if (tabBox()->isDisplayed())
|
||||||
tab_box->reset(true);
|
tab_box->reset(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue