diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2ef13e59cd..7efb982392 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,7 @@ OPTION(KWIN_BUILD_DECORATIONS "Enable building of KWin decorations." ON)
OPTION(KWIN_BUILD_KCMS "Enable building of KWin configuration modules." ON)
OPTION(KWIN_MOBILE_EFFECTS "Only build effects relevant for mobile devices" OFF)
OPTION(KWIN_BUILD_TABBOX "Enable building of KWin Tabbox functionality" ON)
+OPTION(KWIN_BUILD_TILING "Enable building of KWin Tiling functionality" ON)
OPTION(KWIN_BUILD_DESKTOPCHANGEOSD "Enable building of KWin DesktopChangeOSD funtionality" ON)
OPTION(KWIN_BUILD_SCREENEDGES "Enable building of KWin with screen edge support" ON)
OPTION(KWIN_BUILD_SCRIPTING "Enable building of KWin with scripting support" ON)
@@ -18,6 +19,7 @@ if(KWIN_PLASMA_ACTIVE)
set(KWIN_BUILD_DECORATIONS OFF)
set(KWIN_BUILD_KCMS OFF)
set(KWIN_BUILD_TABBOX OFF)
+ set(KWIN_BUILD_TILING OFF)
set(KWIN_BUILD_DESKTOPCHANGEOSD OFF)
set(KWIN_BUILD_SCREENEDGES OFF)
set(KWIN_BUILD_SCRIPTING OFF)
@@ -144,22 +146,6 @@ set(kwin_KDEINIT_SRCS
compositingprefs.cpp
desktoplayout.cpp
paintredirector.cpp
- tile.cpp
- tiling.cpp
- tilinglayout.cpp
- tilinglayoutfactory.cpp
-
- # tiling layouts
- # spiral
- #tilinglayouts/spiral/spiralfactory.cpp
- tilinglayouts/spiral/spiral.cpp
-
- # columns
- #tilinglayouts/columns/columnsfactory.cpp
- tilinglayouts/columns/columns.cpp
-
- # floating
- tilinglayouts/floating/floating.cpp
)
if(KWIN_BUILD_SCRIPTING)
@@ -193,6 +179,26 @@ if(KWIN_BUILD_TABBOX)
)
endif(KWIN_BUILD_TABBOX)
+if(KWIN_BUILD_TILING)
+ set(
+ kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS}
+ tiling/tile.cpp
+ tiling/tiling.cpp
+ tiling/tilinglayout.cpp
+ tilinglayoutfactory.cpp
+
+ # tiling layouts
+ # spiral
+ tilinglayouts/spiral/spiral.cpp
+
+ # columns
+ tilinglayouts/columns/columns.cpp
+
+ # floating
+ tilinglayouts/floating/floating.cpp
+ )
+endif(KWIN_BUILD_TILING)
+
if(KWIN_BUILD_DESKTOPCHANGEOSD)
set(kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS}
desktopchangeosd.cpp
diff --git a/activation.cpp b/activation.cpp
index 1f67f96a42..911e9e65c8 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -262,9 +262,6 @@ void Workspace::setActiveClient(Client* c, allowed_t)
if (active_client) {
active_client->sl_activated();
}
-
- if (tilingEnabled())
- notifyTilingWindowActivated(active_client);
--set_active_client_recursion;
}
diff --git a/client.cpp b/client.cpp
index c4fdd95d87..46c8effed8 100644
--- a/client.cpp
+++ b/client.cpp
@@ -950,9 +950,6 @@ void Client::minimize(bool avoid_animation)
// TODO: merge signal with s_minimized
emit clientMinimized(this, !avoid_animation);
- // when tiling, request a rearrangement
- workspace()->notifyTilingWindowMinimizeToggled(this);
-
// Update states of all other windows in this group
if (clientGroup())
clientGroup()->updateStates(this);
@@ -978,12 +975,8 @@ void Client::unminimize(bool avoid_animation)
updateAllowedActions();
workspace()->updateMinimizedOfTransients(this);
updateWindowRules();
- workspace()->updateAllTiles();
emit clientUnminimized(this, !avoid_animation);
- // when tiling, request a rearrangement
- workspace()->notifyTilingWindowMinimizeToggled(this);
-
// Update states of all other windows in this group
if (clientGroup())
clientGroup()->updateStates(this);
diff --git a/config-kwin.h.cmake b/config-kwin.h.cmake
index 8c8c9d9011..b5bd9b6f08 100644
--- a/config-kwin.h.cmake
+++ b/config-kwin.h.cmake
@@ -2,6 +2,7 @@
#cmakedefine HAVE_CAPTURY 1
#cmakedefine KWIN_BUILD_DECORATIONS 1
#cmakedefine KWIN_BUILD_TABBOX 1
+#cmakedefine KWIN_BUILD_TILING 1
#cmakedefine KWIN_BUILD_DESKTOPCHANGEOSD 1
#cmakedefine KWIN_BUILD_SCREENEDGES 1
#cmakedefine KWIN_BUILD_SCRIPTING 1
diff --git a/geometry.cpp b/geometry.cpp
index a357162b15..af6ce8c50c 100644
--- a/geometry.cpp
+++ b/geometry.cpp
@@ -50,6 +50,9 @@ along with this program. If not, see .
#include
#include
#include "outline.h"
+#ifdef KWIN_BUILD_TILING
+#include "tiling/tiling.h"
+#endif
namespace KWin
{
@@ -2032,7 +2035,9 @@ void Client::move(int x, int y, ForceGeometry_t force)
workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder();
workspace()->checkUnredirect();
- workspace()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom);
+#ifdef KWIN_BUILD_TILING
+ workspace()->tiling()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom);
+#endif
// client itself is not damaged
const QRect deco_rect = decorationRect().translated(geom.x(), geom.y());
addWorkspaceRepaint(deco_rect_before_block);
@@ -2590,17 +2595,26 @@ void Client::finishMoveResize(bool cancel)
leaveMoveResize();
- if (workspace()->tilingEnabled()) {
+#ifdef KWIN_BUILD_TILING
+ if (workspace()->tiling()->isEnabled()) {
if (wasResize)
- workspace()->notifyTilingWindowResizeDone(this, moveResizeGeom, initialMoveResizeGeom, cancel);
+ workspace()->tiling()->notifyTilingWindowResizeDone(this, moveResizeGeom, initialMoveResizeGeom, cancel);
else if (wasMove)
- workspace()->notifyTilingWindowMoveDone(this, moveResizeGeom, initialMoveResizeGeom, cancel);
+ workspace()->tiling()->notifyTilingWindowMoveDone(this, moveResizeGeom, initialMoveResizeGeom, cancel);
} else {
if (cancel)
setGeometry(initialMoveResizeGeom);
else
setGeometry(moveResizeGeom);
}
+#else
+ if (cancel)
+ setGeometry(initialMoveResizeGeom);
+ else
+ setGeometry(moveResizeGeom);
+ Q_UNUSED(wasResize);
+ Q_UNUSED(wasMove);
+#endif
if (cancel)
setGeometry(initialMoveResizeGeom);
@@ -2762,10 +2776,12 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
bool update = false;
if (isResize()) {
+#ifdef KWIN_BUILD_TILING
// query layout for supported resize mode
- if (workspace()->tilingEnabled()) {
- mode = workspace()->supportedTilingResizeMode(this, mode);
+ if (workspace()->tiling()->isEnabled()) {
+ mode = workspace()->tiling()->supportedTilingResizeMode(this, mode);
}
+#endif
// first resize (without checking constrains), then snap, then check bounds, then check constrains
QRect orig = initialMoveResizeGeom;
Sizemode sizemode = SizemodeAny;
@@ -2799,18 +2815,22 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
sizemode = SizemodeFixedW;
break;
case PositionCenter:
+#ifdef KWIN_BUILD_TILING
// exception for tiling
// Center means no resizing allowed
- if (workspace()->tilingEnabled()) {
+ if (workspace()->tiling()->isEnabled()) {
finishMoveResize(false);
buttonDown = false;
return;
}
+#endif
default:
abort();
break;
}
- workspace()->notifyTilingWindowResize(this, moveResizeGeom, initialMoveResizeGeom);
+#ifdef KWIN_BUILD_TILING
+ workspace()->tiling()->notifyTilingWindowResize(this, moveResizeGeom, initialMoveResizeGeom);
+#endif
// adjust new size to snap to other windows/borders
moveResizeGeom = workspace()->adjustClientSize(this, moveResizeGeom, mode);
@@ -2968,7 +2988,9 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
performMoveResize();
if (isMove()) {
- workspace()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom);
+#ifdef KWIN_BUILD_TILING
+ workspace()->tiling()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom);
+#endif
#ifdef KWIN_BUILD_SCREENEDGES
workspace()->screenEdge()->check(globalPos, xTime());
#endif
@@ -2986,8 +3008,10 @@ void Client::performMoveResize()
sendSyncRequest();
}
#endif
- if (!workspace()->tilingEnabled())
+#ifdef KWIN_BUILD_TILING
+ if (!workspace()->tiling()->isEnabled())
setGeometry(moveResizeGeom);
+#endif
positionGeometryTip();
emit clientStepUserMovedResized(this, moveResizeGeom);
}
diff --git a/kwinbindings.cpp b/kwinbindings.cpp
index 0d818570e6..0bea892be5 100644
--- a/kwinbindings.cpp
+++ b/kwinbindings.cpp
@@ -188,22 +188,6 @@ DEF(I18N_NOOP("Kill Window"), Qt::CTRL + Qt::ALT + Qt::Key_
DEF(I18N_NOOP("Block Global Shortcuts"), 0, slotDisableGlobalShortcuts());
DEF(I18N_NOOP("Suspend Compositing"), Qt::SHIFT + Qt::ALT + Qt::Key_F12, slotToggleCompositing());
-a = actionCollection->addAction("Group:Tiling");
-a->setText(i18n("Tiling"));
-DEF(I18N_NOOP("Enable/Disable Tiling"), Qt::SHIFT + Qt::ALT + Qt::Key_F11, slotToggleTiling());
-DEF(I18N_NOOP("Toggle Floating"), Qt::META + Qt::Key_F, slotToggleFloating());
-
-DEF(I18N_NOOP("Switch Focus Left") , Qt::META + Qt::Key_H, slotFocusTileLeft());
-DEF(I18N_NOOP("Switch Focus Right") , Qt::META + Qt::Key_L, slotFocusTileRight());
-DEF(I18N_NOOP("Switch Focus Up") , Qt::META + Qt::Key_K, slotFocusTileTop());
-DEF(I18N_NOOP("Switch Focus Down") , Qt::META + Qt::Key_J, slotFocusTileBottom());
-DEF(I18N_NOOP("Move Window Left") , Qt::SHIFT + Qt::META + Qt::Key_H, slotMoveTileLeft());
-DEF(I18N_NOOP("Move Window Right") , Qt::SHIFT + Qt::META + Qt::Key_L, slotMoveTileRight());
-DEF(I18N_NOOP("Move Window Up") , Qt::SHIFT + Qt::META + Qt::Key_K, slotMoveTileTop());
-DEF(I18N_NOOP("Move Window Down") , Qt::SHIFT + Qt::META + Qt::Key_J, slotMoveTileBottom());
-DEF(I18N_NOOP("Next Layout"), Qt::META + Qt::Key_PageDown, slotNextTileLayout());
-DEF(I18N_NOOP("Previous Layout"), Qt::META + Qt::Key_PageUp, slotPreviousTileLayout());
-
#undef DEF
#undef DEF2
diff --git a/sm.cpp b/sm.cpp
index db44ce008d..113018cdf3 100644
--- a/sm.cpp
+++ b/sm.cpp
@@ -34,6 +34,9 @@ along with this program. If not, see .
#include
#include
#include
+#ifdef KWIN_BUILD_TILING
+#include "tiling/tiling.h"
+#endif
namespace KWin
{
@@ -84,11 +87,13 @@ void Workspace::storeSession(KConfig* config, SMSavePhase phase)
int active_client = -1;
if (phase == SMSavePhase2 || phase == SMSavePhase2Full) {
- cg.writeEntry("tiling", tilingEnabled());
- if (tilingEnabled()) {
+#ifdef KWIN_BUILD_TILING
+ cg.writeEntry("tiling", m_tiling->isEnabled());
+ if (m_tiling->isEnabled()) {
kDebug(1212) << "Tiling was ON";
- setTilingEnabled(false);
+ m_tiling->setEnabled(false);
}
+#endif
}
for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) {
@@ -273,7 +278,9 @@ void Workspace::loadSessionInfo()
session.clear();
KConfigGroup cg(kapp->sessionConfig(), "Session");
- setTilingEnabled(cg.readEntry("tiling", false));
+#ifdef KWIN_BUILD_TILING
+ m_tiling->setEnabled(cg.readEntry("tiling", false));
+#endif
addSessionInfo(cg);
}
diff --git a/tiling.cpp b/tiling.cpp
deleted file mode 100644
index 85b22274db..0000000000
--- a/tiling.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/********************************************************************
- KWin - the KDE window manager
- This file is part of the KDE project.
-
-Copyright (C) 2009 Nikhil Marathe
-
-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 .
-*********************************************************************/
-
-// all the tiling related code that is extensions to existing KWin classes
-// Includes Workspace for now
-
-#include "client.h"
-#include "workspace.h"
-#include "tile.h"
-#include "tilinglayout.h"
-#include "tilinglayoutfactory.h"
-
-#include
-#include
-#include
-#include
-
-
-namespace KWin
-{
-
-bool Workspace::tilingEnabled() const
-{
- return tilingEnabled_;
-}
-
-void Workspace::setTilingEnabled(bool tiling)
-{
- if (tilingEnabled() == tiling) return;
-
- tilingEnabled_ = tiling;
-
- KSharedConfig::Ptr _config = KGlobal::config();
- KConfigGroup config(_config, "Windows");
- config.writeEntry("TilingOn", tilingEnabled_);
- config.sync();
- options->tilingOn = tilingEnabled_;
- options->tilingLayout = static_cast(config.readEntry("TilingDefaultLayout", 0));
- options->tilingRaisePolicy = config.readEntry("TilingRaisePolicy", 0);
-
- if (tilingEnabled_) {
- tilingLayouts.resize(numberOfDesktops() + 1);
- foreach (Client * c, stackingOrder()) {
- createTile(c);
- }
- } else {
- qDeleteAll(tilingLayouts);
- tilingLayouts.clear();
- }
-}
-
-void Workspace::slotToggleTiling()
-{
- if (tilingEnabled()) {
- setTilingEnabled(false);
- QString message = i18n("Tiling Disabled");
- KNotification::event("tilingdisabled", message, QPixmap(), NULL, KNotification::CloseOnTimeout, KComponentData("kwin"));
- } else {
- setTilingEnabled(true);
- QString message = i18n("Tiling Enabled");
- KNotification::event("tilingenabled", message, QPixmap(), NULL, KNotification::CloseOnTimeout, KComponentData("kwin"));
- }
-}
-
-void Workspace::createTile(Client *c)
-{
- if (c == NULL)
- return;
-
- if (c->desktop() < 0 || c->desktop() >= tilingLayouts.size()) return;
-
- kDebug(1212) << "Now tiling " << c->caption();
- if (!tilingEnabled() || !tileable(c))
- return;
-
- Tile *t = new Tile(c, clientArea(PlacementArea, c));
- if (!tileable(c)) {
- kDebug(1212) << c->caption() << "is not tileable";
- t->floatTile();
- }
-
- if (!tilingLayouts.value(c->desktop())) {
- tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, this);
- }
- tilingLayouts[c->desktop()]->addTile(t);
- tilingLayouts[c->desktop()]->commit();
-}
-
-void Workspace::removeTile(Client *c)
-{
- if (tilingLayouts[ c->desktop()])
- tilingLayouts[ c->desktop()]->removeTile(c);
-}
-
-bool Workspace::tileable(Client *c)
-{
-
- kDebug(1212) << c->caption();
- KWindowInfo info = KWindowSystem::windowInfo(c->window(), -1U, NET::WM2WindowClass);
- kDebug(1212) << "WINDOW CLASS IS " << info.windowClassClass();
- if (info.windowClassClass() == "Plasma-desktop") {
- return false;
- }
- // TODO: if application specific settings
- // to ignore, put them here
-
- if (!c->isNormalWindow()) {
- return false;
- }
-
- // 0 means tile it, if we get 1 (floating), don't tile
- if (c->rules()->checkTilingOption(0) == 1) {
- return false;
- }
-
- kDebug() << "Tiling" << c;
- return true;
-}
-
-void Workspace::belowCursor()
-{
- // TODO
-}
-
-Tile* Workspace::getNiceTile() const
-{
- if (!tilingEnabled()) return NULL;
- if (!tilingLayouts.value(activeClient()->desktop())) return NULL;
-
- return tilingLayouts[ activeClient()->desktop()]->findTile(activeClient());
- // TODO
-}
-
-void Workspace::updateAllTiles()
-{
- foreach (TilingLayout * t, tilingLayouts) {
- if (!t) continue;
- t->commit();
- }
-}
-
-/*
- * Resize the neighbouring clients to close any gaps
- */
-void Workspace::notifyTilingWindowResize(Client *c, const QRect &moveResizeGeom, const QRect &orig)
-{
- if (tilingLayouts.value(c->desktop()) == NULL)
- return;
- tilingLayouts[ c->desktop()]->clientResized(c, moveResizeGeom, orig);
-}
-
-void Workspace::notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, const QRect &orig)
-{
- if (tilingLayouts.value(c->desktop()) == NULL) {
- return;
- }
- tilingLayouts[ c->desktop()]->clientMoved(c, moveResizeGeom, orig);
- updateAllTiles();
-}
-
-void Workspace::notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled)
-{
- if (canceled)
- notifyTilingWindowResize(c, orig, moveResizeGeom);
- else
- notifyTilingWindowResize(c, moveResizeGeom, orig);
-}
-
-void Workspace::notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled)
-{
- if (canceled)
- notifyTilingWindowMove(c, orig, moveResizeGeom);
- else
- notifyTilingWindowMove(c, moveResizeGeom, orig);
-}
-
-void Workspace::notifyTilingWindowDesktopChanged(Client *c, int old_desktop)
-{
- if (c->desktop() < 1 || c->desktop() > numberOfDesktops())
- return;
-
- if (tilingLayouts.value(old_desktop)) {
- Tile *t = tilingLayouts[ old_desktop ]->findTile(c);
-
- // TODO: copied from createTile(), move this into separate method?
- if (!tilingLayouts.value(c->desktop())) {
- tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, this);
- }
-
- if (t)
- tilingLayouts[ c->desktop()]->addTile(t);
-
- tilingLayouts[ old_desktop ]->removeTile(c);
- tilingLayouts[ old_desktop ]->commit();
- }
-}
-
-/*
- * Implements the 3 raising modes in Window Behaviour -> Advanced
- */
-void Workspace::notifyTilingWindowActivated(Client *c)
-{
- if (c == NULL)
- return;
-
- if (options->tilingRaisePolicy == 1) // individual raise/lowers
- return;
-
- if (tilingLayouts.value(c->desktop())) {
- QList tiles = tilingLayouts[ c->desktop()]->tiles();
-
- StackingUpdatesBlocker blocker(this);
-
- Tile *tile_to_raise = tilingLayouts[ c->desktop()]->findTile(c);
-
- if (!tile_to_raise) {
- return;
- }
-
- kDebug(1212) << "FOUND TILE";
- bool raise_floating = false;
- if (options->tilingRaisePolicy == 2) // floating always on top
- raise_floating = true;
- else
- raise_floating = tile_to_raise->floating();
-
- foreach (Tile * t, tiles) {
- if (t->floating() == raise_floating && t != tile_to_raise)
- raiseClient(t->client());
- }
- // raise the current tile last so that it ends up on top
- // but only if it supposed to be raised, required to support tilingRaisePolicy
- kDebug(1212) << "Raise floating? " << raise_floating << "to raise is floating?" << tile_to_raise->floating();
- if (tile_to_raise->floating() == raise_floating)
- raiseClient(tile_to_raise->client());
- }
-}
-
-void Workspace::notifyTilingWindowMinimizeToggled(Client *c)
-{
- if (tilingLayouts.value(c->desktop())) {
- tilingLayouts[ c->desktop()]->clientMinimizeToggled(c);
- }
-}
-
-void Workspace::notifyTilingWindowMaximized(Client *c, Options::WindowOperation op)
-{
- if (tilingLayouts.value(c->desktop())) {
- Tile *t = tilingLayouts[ c->desktop()]->findTile(c);
- if (!t) {
- createTile(c);
- t = tilingLayouts[ c->desktop()]->findTile(c);
-
- // if still no tile, it couldn't be tiled
- // so ignore it
- if (!t)
- return;
- }
-
- // if window IS tiled and a maximize
- // is attempted, make the window float.
- // That is all we do since that can
- // mess up the layout.
- // In all other cases, don't do
- // anything, let the user manage toggling
- // using Meta+F
- if (!t->floating()
- && (op == Options::MaximizeOp
- || op == Options::HMaximizeOp
- || op == Options::VMaximizeOp)) {
- tilingLayouts[ c->desktop()]->toggleFloatTile(c);
- }
-
- }
-}
-
-Tile* Workspace::findAdjacentTile(Tile *ref, int d)
-{
- QRect reference = ref->geometry();
- QPoint origin = reference.center();
-
- Tile *closest = NULL;
- int minDist = -1;
-
- QList tiles = tilingLayouts[ ref->client()->desktop()]->tiles();
-
- foreach (Tile * t, tiles) {
- if (t->client() == ref->client() || t->ignoreGeometry())
- continue;
-
- bool consider = false;
-
- QRect other = t->geometry();
- QPoint otherCenter = other.center();
-
- switch(d) {
- case Tile::Top:
- consider = otherCenter.y() < origin.y()
- && other.bottom() < reference.top();
- break;
-
- case Tile::Right:
- consider = otherCenter.x() > origin.x()
- && other.left() > reference.right();
- break;
-
- case Tile::Bottom:
- consider = otherCenter.y() > origin.y()
- && other.top() > reference.bottom();
- break;
-
- case Tile::Left:
- consider = otherCenter.x() < origin.x()
- && other.right() < reference.left();
- break;
-
- default:
- abort();
- }
-
- if (consider) {
- int dist = (otherCenter - origin).manhattanLength();
- if (minDist > dist || minDist < 0) {
- minDist = dist;
- closest = t;
- }
- }
- }
- return closest;
-}
-
-void Workspace::focusTile(int d)
-{
- Tile *t = getNiceTile();
- if (t) {
- Tile *adj = findAdjacentTile(t, d);
- if (adj)
- activateClient(adj->client());
- }
-}
-
-void Workspace::moveTile(int d)
-{
- Tile *t = getNiceTile();
- if (t) {
- Tile* adj = findAdjacentTile(t, d);
-
- tilingLayouts[ t->client()->desktop()]->swapTiles(t, adj);
- }
-}
-
-void Workspace::slotFocusTileLeft()
-{
- focusTile(Tile::Left);
-}
-
-void Workspace::slotFocusTileRight()
-{
- focusTile(Tile::Right);
-}
-
-void Workspace::slotFocusTileTop()
-{
- focusTile(Tile::Top);
-}
-
-void Workspace::slotFocusTileBottom()
-{
- focusTile(Tile::Bottom);
-}
-
-void Workspace::slotMoveTileLeft()
-{
- moveTile(Tile::Left);
-}
-
-void Workspace::slotMoveTileRight()
-{
- moveTile(Tile::Right);
-}
-
-void Workspace::slotMoveTileTop()
-{
- moveTile(Tile::Top);
-}
-
-void Workspace::slotMoveTileBottom()
-{
- moveTile(Tile::Bottom);
-}
-
-void Workspace::slotToggleFloating()
-{
- Client *c = activeClient();
- if (tilingLayouts.value(c->desktop())) {
- tilingLayouts[ c->desktop()]->toggleFloatTile(c);
- }
-}
-
-void Workspace::slotNextTileLayout()
-{
- if (tilingLayouts.value(currentDesktop())) {
-
- tilingLayouts.replace(currentDesktop(), TilingLayoutFactory::nextLayout(tilingLayouts[currentDesktop()]));
-
- tilingLayouts[currentDesktop()]->commit();
- }
-}
-
-void Workspace::slotPreviousTileLayout()
-{
- if (tilingLayouts.value(currentDesktop())) {
-
- tilingLayouts.replace(currentDesktop(), TilingLayoutFactory::previousLayout(tilingLayouts[currentDesktop()]));
-
- tilingLayouts[currentDesktop()]->commit();
- }
-}
-
-KDecorationDefines::Position Workspace::supportedTilingResizeMode(Client *c, KDecorationDefines::Position currentMode)
-{
- if (tilingLayouts.value(c->desktop())) {
- return tilingLayouts[c->desktop()]->resizeMode(c, currentMode);
- }
- return currentMode;
-}
-
-void Workspace::dumpTiles() const
-{
- foreach (TilingLayout * t, tilingLayouts) {
- if (!t) {
- kDebug(1212) << "EMPTY DESKTOP";
- continue;
- }
- kDebug(1212) << "Desktop" << tilingLayouts.indexOf(t);
- foreach (Tile * tile, t->tiles()) {
- tile->dumpTile("--");
- }
- }
-}
-} // namespace
-
diff --git a/tile.cpp b/tiling/tile.cpp
similarity index 97%
rename from tile.cpp
rename to tiling/tile.cpp
index a188129581..ee1f848a09 100644
--- a/tile.cpp
+++ b/tiling/tile.cpp
@@ -26,6 +26,7 @@ along with this program. If not, see .
#include "client.h"
#include "workspace.h"
+#include "tiling/tiling.h"
namespace KWin
{
@@ -95,7 +96,7 @@ void Tile::floatTile()
restorePreviousGeometry();
commit();
- client()->workspace()->notifyTilingWindowActivated(client());
+ client()->workspace()->tiling()->notifyTilingWindowActivated(client());
// TODO: notify layout manager
}
diff --git a/tile.h b/tiling/tile.h
similarity index 100%
rename from tile.h
rename to tiling/tile.h
diff --git a/tiling/tiling.cpp b/tiling/tiling.cpp
new file mode 100644
index 0000000000..0b8fb95e66
--- /dev/null
+++ b/tiling/tiling.cpp
@@ -0,0 +1,520 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2009 Nikhil Marathe
+Copyright (C) 2011 Arthur Arlt
+
+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 .
+*********************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "tiling/tile.h"
+#include "tiling/tilinglayout.h"
+#include "tilinglayoutfactory.h"
+#include "workspace.h"
+
+namespace KWin {
+Tiling::Tiling(KWin::Workspace* w)
+ : QObject(w)
+ , m_workspace(w)
+ , m_enabled(false)
+{
+}
+
+Tiling::~Tiling()
+{
+}
+
+void Tiling::initShortcuts(KActionCollection* keys){
+ KAction *a = NULL;
+ #define KEY( name, key, fnSlot ) \
+ a = keys->addAction( name ); \
+ a->setText( i18n( name ) ); \
+ qobject_cast( a )->setGlobalShortcut(KShortcut(key)); \
+ connect(a, SIGNAL(triggered(bool)), SLOT(fnSlot));
+
+ a = keys->addAction("Group:Tiling");
+ a->setText(i18n("Tiling"));
+ KEY(I18N_NOOP("Enable/Disable Tiling"), Qt::SHIFT + Qt::ALT + Qt::Key_F11, slotToggleTiling());
+ KEY(I18N_NOOP("Toggle Floating"), Qt::META + Qt::Key_F, slotToggleFloating());
+
+ KEY(I18N_NOOP("Switch Focus Left") , Qt::META + Qt::Key_H, slotFocusTileLeft());
+ KEY(I18N_NOOP("Switch Focus Right") , Qt::META + Qt::Key_L, slotFocusTileRight());
+ KEY(I18N_NOOP("Switch Focus Up") , Qt::META + Qt::Key_K, slotFocusTileTop());
+ KEY(I18N_NOOP("Switch Focus Down") , Qt::META + Qt::Key_J, slotFocusTileBottom());
+ KEY(I18N_NOOP("Move Window Left") , Qt::SHIFT + Qt::META + Qt::Key_H, slotMoveTileLeft());
+ KEY(I18N_NOOP("Move Window Right") , Qt::SHIFT + Qt::META + Qt::Key_L, slotMoveTileRight());
+ KEY(I18N_NOOP("Move Window Up") , Qt::SHIFT + Qt::META + Qt::Key_K, slotMoveTileTop());
+ KEY(I18N_NOOP("Move Window Down") , Qt::SHIFT + Qt::META + Qt::Key_J, slotMoveTileBottom());
+ KEY(I18N_NOOP("Next Layout"), Qt::META + Qt::Key_PageDown, slotNextTileLayout());
+ KEY(I18N_NOOP("Previous Layout"), Qt::META + Qt::Key_PageUp, slotPreviousTileLayout());
+
+}
+
+bool Tiling::isEnabled() const
+{
+ return m_enabled;
+}
+
+void Tiling::setEnabled(bool tiling)
+{
+ if (isEnabled() == tiling) return;
+
+ m_enabled = tiling;
+
+ KSharedConfig::Ptr _config = KGlobal::config();
+ KConfigGroup config(_config, "Windows");
+ config.writeEntry("TilingOn", m_enabled);
+ config.sync();
+ options->tilingOn = m_enabled;
+ options->tilingLayout = static_cast(config.readEntry("TilingDefaultLayout", 0));
+ options->tilingRaisePolicy = config.readEntry("TilingRaisePolicy", 0);
+
+ if (m_enabled) {
+ connect(m_workspace, SIGNAL(clientAdded(KWin::Client*)), this, SLOT(createTile(KWin::Client*)));
+ connect(m_workspace, SIGNAL(clientAdded(KWin::Client*)), this, SLOT(slotResizeTilingLayouts()));
+ connect(m_workspace, SIGNAL(numberDesktopsChanged(int)), this, SLOT(slotResizeTilingLayouts()));
+ connect(m_workspace, SIGNAL(clientRemoved(KWin::Client*)), this, SLOT(removeTile(KWin::Client*)));
+ connect(m_workspace, SIGNAL(clientActivated(KWin::Client*)), this, SLOT(notifyTilingWindowActivated(KWin::Client*)));
+ m_tilingLayouts.resize(Workspace::self()->numberOfDesktops() + 1);
+ foreach (Client * c, Workspace::self()->stackingOrder()) {
+ createTile(c);
+ }
+ } else {
+ disconnect(m_workspace, SIGNAL(clientAdded(KWin::Client*)));
+ disconnect(m_workspace, SIGNAL(numberDesktopsChanged(int)));
+ disconnect(m_workspace, SIGNAL(clientRemoved(KWin::Client*)));
+ qDeleteAll(m_tilingLayouts);
+ m_tilingLayouts.clear();
+ }
+}
+
+void Tiling::slotToggleTiling()
+{
+ if (isEnabled()) {
+ setEnabled(false);
+ QString message = i18n("Tiling Disabled");
+ KNotification::event("tilingdisabled", message, QPixmap(), NULL, KNotification::CloseOnTimeout, KComponentData("kwin"));
+ } else {
+ setEnabled(true);
+ QString message = i18n("Tiling Enabled");
+ KNotification::event("tilingenabled", message, QPixmap(), NULL, KNotification::CloseOnTimeout, KComponentData("kwin"));
+ }
+}
+
+void Tiling::createTile(Client* c)
+{
+ if (c == NULL)
+ return;
+
+ if (c->desktop() < 0 || c->desktop() >= m_tilingLayouts.size()) return;
+
+ kDebug(1212) << "Now tiling " << c->caption();
+ if (!isEnabled() || !tileable(c))
+ return;
+
+ Tile *t = new Tile(c, Workspace::self()->clientArea(PlacementArea, c));
+ if (!tileable(c)) {
+ kDebug(1212) << c->caption() << "is not tileable";
+ t->floatTile();
+ }
+
+ if (!m_tilingLayouts.value(c->desktop())) {
+ m_tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, m_workspace);
+ m_tilingLayouts[c->desktop()]->setParent(this);
+ }
+ m_tilingLayouts[c->desktop()]->addTile(t);
+ m_tilingLayouts[c->desktop()]->commit();
+ // if tiling is activated, connect to Client's signals and react with rearrangement when (un)minimizing
+ connect(c, SIGNAL(clientMinimized(KWin::Client*,bool)), this, SLOT(notifyTilingWindowMinimizeToggled(KWin::Client*)));
+ connect(c, SIGNAL(clientUnminimized(KWin::Client*,bool)), this, SLOT(notifyTilingWindowMinimizeToggled(KWin::Client*)));
+ connect(c, SIGNAL(s_unminimized()), this, SLOT(updateAllTiles()));
+}
+
+void Tiling::removeTile(Client *c)
+{
+ if (!m_tilingLayouts.value(c->desktop())) {
+ return;
+ }
+ if (m_tilingLayouts[ c->desktop()])
+ m_tilingLayouts[ c->desktop()]->removeTile(c);
+}
+
+bool Tiling::tileable(Client* c)
+{
+ kDebug(1212) << c->caption();
+ KWindowInfo info = KWindowSystem::windowInfo(c->window(), -1U, NET::WM2WindowClass);
+ kDebug(1212) << "WINDOW CLASS IS " << info.windowClassClass();
+ if (info.windowClassClass() == "Plasma-desktop") {
+ return false;
+ }
+ // TODO: if application specific settings
+ // to ignore, put them here
+
+ if (!c->isNormalWindow()) {
+ return false;
+ }
+
+ // 0 means tile it, if we get 1 (floating), don't tile
+ if (c->rules()->checkTilingOption(0) == 1) {
+ return false;
+ }
+
+ kDebug() << "Tiling" << c;
+ return true;
+}
+
+void Tiling::belowCursor()
+{
+ // TODO
+}
+
+Tile* Tiling::getNiceTile() const
+{
+ if (!isEnabled()) return NULL;
+ if (!m_tilingLayouts.value(m_workspace->activeClient()->desktop())) return NULL;
+
+ return m_tilingLayouts[ m_workspace->activeClient()->desktop()]->findTile(m_workspace->activeClient());
+ // TODO
+}
+
+void Tiling::updateAllTiles()
+{
+ foreach (TilingLayout * t, m_tilingLayouts) {
+ if (!t) continue;
+ t->commit();
+ }
+}
+
+/*
+ * Resize the neighbouring clients to close any gaps
+ */
+void Tiling::notifyTilingWindowResize(Client *c, const QRect &moveResizeGeom, const QRect &orig)
+{
+ if (m_tilingLayouts.value(c->desktop()) == NULL)
+ return;
+ m_tilingLayouts[ c->desktop()]->clientResized(c, moveResizeGeom, orig);
+}
+
+void Tiling::notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, const QRect &orig)
+{
+ if (m_tilingLayouts.value(c->desktop()) == NULL) {
+ return;
+ }
+ m_tilingLayouts[ c->desktop()]->clientMoved(c, moveResizeGeom, orig);
+ updateAllTiles();
+}
+
+void Tiling::notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled)
+{
+ if (canceled)
+ notifyTilingWindowResize(c, orig, moveResizeGeom);
+ else
+ notifyTilingWindowResize(c, moveResizeGeom, orig);
+}
+
+void Tiling::notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled)
+{
+ if (canceled)
+ notifyTilingWindowMove(c, orig, moveResizeGeom);
+ else
+ notifyTilingWindowMove(c, moveResizeGeom, orig);
+}
+
+void Tiling::notifyTilingWindowDesktopChanged(Client *c, int old_desktop)
+{
+ if (c->desktop() < 1 || c->desktop() > m_workspace->numberOfDesktops())
+ return;
+
+ if (m_tilingLayouts.value(old_desktop)) {
+ Tile *t = m_tilingLayouts[ old_desktop ]->findTile(c);
+
+ // TODO: copied from createTile(), move this into separate method?
+ if (!m_tilingLayouts.value(c->desktop())) {
+ m_tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, m_workspace);
+ }
+
+ if (t)
+ m_tilingLayouts[ c->desktop()]->addTile(t);
+
+ m_tilingLayouts[ old_desktop ]->removeTile(c);
+ m_tilingLayouts[ old_desktop ]->commit();
+ }
+}
+
+/*
+ * Implements the 3 raising modes in Window Behaviour -> Advanced
+ */
+void Tiling::notifyTilingWindowActivated(KWin::Client *c)
+{
+ if (c == NULL)
+ return;
+
+ if (options->tilingRaisePolicy == 1) // individual raise/lowers
+ return;
+
+ if (m_tilingLayouts.value(c->desktop())) {
+ QList tiles = m_tilingLayouts[ c->desktop()]->tiles();
+
+ StackingUpdatesBlocker blocker(m_workspace);
+
+ Tile *tile_to_raise = m_tilingLayouts[ c->desktop()]->findTile(c);
+
+ if (!tile_to_raise) {
+ return;
+ }
+
+ kDebug(1212) << "FOUND TILE";
+ bool raise_floating = false;
+ if (options->tilingRaisePolicy == 2) // floating always on top
+ raise_floating = true;
+ else
+ raise_floating = tile_to_raise->floating();
+
+ foreach (Tile * t, tiles) {
+ if (t->floating() == raise_floating && t != tile_to_raise)
+ m_workspace->raiseClient(t->client());
+ }
+ // raise the current tile last so that it ends up on top
+ // but only if it supposed to be raised, required to support tilingRaisePolicy
+ kDebug(1212) << "Raise floating? " << raise_floating << "to raise is floating?" << tile_to_raise->floating();
+ if (tile_to_raise->floating() == raise_floating)
+ m_workspace->raiseClient(tile_to_raise->client());
+ }
+}
+
+void Tiling::notifyTilingWindowMinimizeToggled(KWin::Client* c)
+{
+ if (m_tilingLayouts.value(c->desktop())) {
+ m_tilingLayouts[ c->desktop()]->clientMinimizeToggled(c);
+ }
+}
+
+void Tiling::notifyTilingWindowMaximized(Client *c, Options::WindowOperation op)
+{
+ if (m_tilingLayouts.value(c->desktop())) {
+ Tile *t = m_tilingLayouts[ c->desktop()]->findTile(c);
+ if (!t) {
+ createTile(c);
+ t = m_tilingLayouts[ c->desktop()]->findTile(c);
+
+ // if still no tile, it couldn't be tiled
+ // so ignore it
+ if (!t)
+ return;
+ }
+
+ // if window IS tiled and a maximize
+ // is attempted, make the window float.
+ // That is all we do since that can
+ // mess up the layout.
+ // In all other cases, don't do
+ // anything, let the user manage toggling
+ // using Meta+F
+ if (!t->floating()
+ && (op == Options::MaximizeOp
+ || op == Options::HMaximizeOp
+ || op == Options::VMaximizeOp)) {
+ m_tilingLayouts[ c->desktop()]->toggleFloatTile(c);
+ }
+
+ }
+}
+
+Tile* Tiling::findAdjacentTile(Tile *ref, int d)
+{
+ QRect reference = ref->geometry();
+ QPoint origin = reference.center();
+
+ Tile *closest = NULL;
+ int minDist = -1;
+
+ QList tiles = m_tilingLayouts[ ref->client()->desktop()]->tiles();
+
+ foreach (Tile * t, tiles) {
+ if (t->client() == ref->client() || t->ignoreGeometry())
+ continue;
+
+ bool consider = false;
+
+ QRect other = t->geometry();
+ QPoint otherCenter = other.center();
+
+ switch(d) {
+ case Tile::Top:
+ consider = otherCenter.y() < origin.y()
+ && other.bottom() < reference.top();
+ break;
+
+ case Tile::Right:
+ consider = otherCenter.x() > origin.x()
+ && other.left() > reference.right();
+ break;
+
+ case Tile::Bottom:
+ consider = otherCenter.y() > origin.y()
+ && other.top() > reference.bottom();
+ break;
+
+ case Tile::Left:
+ consider = otherCenter.x() < origin.x()
+ && other.right() < reference.left();
+ break;
+
+ default:
+ abort();
+ }
+
+ if (consider) {
+ int dist = (otherCenter - origin).manhattanLength();
+ if (minDist > dist || minDist < 0) {
+ minDist = dist;
+ closest = t;
+ }
+ }
+ }
+ return closest;
+}
+
+void Tiling::focusTile(int d)
+{
+ Tile *t = getNiceTile();
+ if (t) {
+ Tile *adj = findAdjacentTile(t, d);
+ if (adj)
+ m_workspace->activateClient(adj->client());
+ }
+}
+
+void Tiling::moveTile(int d)
+{
+ Tile *t = getNiceTile();
+ if (t) {
+ Tile* adj = findAdjacentTile(t, d);
+
+ m_tilingLayouts[ t->client()->desktop()]->swapTiles(t, adj);
+ }
+}
+
+void Tiling::slotFocusTileLeft()
+{
+ focusTile(Tile::Left);
+}
+
+void Tiling::slotFocusTileRight()
+{
+ focusTile(Tile::Right);
+}
+
+void Tiling::slotFocusTileTop()
+{
+ focusTile(Tile::Top);
+}
+
+void Tiling::slotFocusTileBottom()
+{
+ focusTile(Tile::Bottom);
+}
+
+void Tiling::slotMoveTileLeft()
+{
+ moveTile(Tile::Left);
+}
+
+void Tiling::slotMoveTileRight()
+{
+ moveTile(Tile::Right);
+}
+
+void Tiling::slotMoveTileTop()
+{
+ moveTile(Tile::Top);
+}
+
+void Tiling::slotMoveTileBottom()
+{
+ moveTile(Tile::Bottom);
+}
+
+void Tiling::slotToggleFloating()
+{
+ Client *c = m_workspace->activeClient();
+ if (m_tilingLayouts.value(c->desktop())) {
+ m_tilingLayouts[ c->desktop()]->toggleFloatTile(c);
+ }
+}
+
+void Tiling::slotNextTileLayout()
+{
+ if (m_tilingLayouts.value(m_workspace->currentDesktop())) {
+
+ m_tilingLayouts.replace(m_workspace->currentDesktop(), TilingLayoutFactory::nextLayout(m_tilingLayouts[m_workspace->currentDesktop()]));
+
+ m_tilingLayouts[m_workspace->currentDesktop()]->commit();
+ }
+}
+
+void Tiling::slotPreviousTileLayout()
+{
+ if (m_tilingLayouts.value(m_workspace->currentDesktop())) {
+
+ m_tilingLayouts.replace(m_workspace->currentDesktop(), TilingLayoutFactory::previousLayout(m_tilingLayouts[m_workspace->currentDesktop()]));
+
+ m_tilingLayouts[m_workspace->currentDesktop()]->commit();
+ }
+}
+
+KDecorationDefines::Position Tiling::supportedTilingResizeMode(Client *c, KDecorationDefines::Position currentMode)
+{
+ if (m_tilingLayouts.value(c->desktop())) {
+ return m_tilingLayouts[c->desktop()]->resizeMode(c, currentMode);
+ }
+ return currentMode;
+}
+
+void Tiling::dumpTiles() const
+{
+ foreach (TilingLayout * t, m_tilingLayouts) {
+ if (!t) {
+ kDebug(1212) << "EMPTY DESKTOP";
+ continue;
+ }
+ kDebug(1212) << "Desktop" << m_tilingLayouts.indexOf(t);
+ foreach (Tile * tile, t->tiles()) {
+ tile->dumpTile("--");
+ }
+ }
+}
+
+const QVector< TilingLayout* >& Tiling::tilingLayouts() const
+{
+ return m_tilingLayouts;
+}
+
+void Tiling::slotResizeTilingLayouts()
+{
+ m_tilingLayouts.resize(m_workspace->numberOfDesktops() + 1);
+}
+
+}
diff --git a/tiling/tiling.h b/tiling/tiling.h
new file mode 100644
index 0000000000..694bd9cde6
--- /dev/null
+++ b/tiling/tiling.h
@@ -0,0 +1,112 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2009 Nikhil Marathe
+Copyright (C) 2011 Arthur Arlt
+
+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 .
+*********************************************************************/
+
+#ifndef KWIN_TILING_H
+#define KWIN_TILING_H
+
+#include
+
+#include "client.h"
+
+#include
+
+namespace KWin {
+
+class Tile;
+class TilingLayout;
+
+class Tiling : public QObject {
+ Q_OBJECT
+public:
+ Tiling(Workspace *w);
+ ~Tiling();
+ bool isEnabled() const;
+ void setEnabled(bool tiling);
+ bool tileable(Client *c);
+ const QVector< TilingLayout* >& tilingLayouts() const;
+ void initShortcuts(KActionCollection* keys);
+
+ // The notification functions are called from
+ // various points in existing code so that
+ // tiling can take any action if required.
+ // They are defined in tiling.cpp
+ void notifyTilingWindowResize(Client *c, const QRect &moveResizeGeom, const QRect &orig);
+ void notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, const QRect &orig);
+ void notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled);
+ void notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled);
+ void notifyTilingWindowDesktopChanged(Client *c, int old_desktop);
+ void notifyTilingWindowMaximized(Client *c, KDecorationDefines::WindowOperation op);
+
+ KDecorationDefines::Position supportedTilingResizeMode(Client *c, KDecorationDefines::Position currentMode);
+
+public Q_SLOTS:
+ void createTile(KWin::Client *c);
+ void removeTile(KWin::Client *c);
+ // user actions, usually bound to shortcuts
+ // and also provided through the D-BUS interface.
+ void slotToggleTiling();
+ void slotToggleFloating();
+ void slotNextTileLayout();
+ void slotPreviousTileLayout();
+
+ // Changes the focused client
+ void slotFocusTileLeft();
+ void slotFocusTileRight();
+ void slotFocusTileTop();
+ void slotFocusTileBottom();
+ // swaps active and adjacent client.
+ void slotMoveTileLeft();
+ void slotMoveTileRight();
+ void slotMoveTileTop();
+ void slotMoveTileBottom();
+ void belowCursor();
+
+ // NOTE: debug method
+ void dumpTiles() const;
+
+ void notifyTilingWindowActivated(KWin::Client *c);
+private:
+ // try to get a decent tile, either the one with
+ // focus or the one below the mouse.
+ Tile* getNiceTile() const;
+ // int, and not Tile::Direction because
+ // we are using a forward declaration for Tile
+ Tile* findAdjacentTile(Tile *ref, int d);
+ void focusTile(int d);
+ void moveTile(int d);
+
+ Workspace* m_workspace;
+ bool m_enabled;
+ // Each tilingLayout is for one virtual desktop.
+ // The length is always one more than the number of
+ // virtual desktops so that we can quickly index them
+ // without having to remember to subtract one.
+ QVector m_tilingLayouts;
+private Q_SLOTS:
+ void slotResizeTilingLayouts();
+ void notifyTilingWindowMinimizeToggled(KWin::Client *c);
+ // updates geometry of tiles on all desktops,
+ // this rearranges the tiles.
+ void updateAllTiles();
+};
+}
+
+#endif // KWIN_TILING_H
\ No newline at end of file
diff --git a/tilinglayout.cpp b/tiling/tilinglayout.cpp
similarity index 95%
rename from tilinglayout.cpp
rename to tiling/tilinglayout.cpp
index 6e1152b15c..0e1d642ad5 100644
--- a/tilinglayout.cpp
+++ b/tiling/tilinglayout.cpp
@@ -18,20 +18,23 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*********************************************************************/
-#include "tilinglayout.h"
+#include "tiling/tilinglayout.h"
#include
#include "client.h"
-#include "tile.h"
+#include "tiling/tile.h"
#include "workspace.h"
+#include "tiling/tiling.h"
namespace KWin
{
TilingLayout::TilingLayout(Workspace *w)
- : m_workspace(w)
+ : QObject()
+ , m_workspace(w)
{
+ connect(m_workspace, SIGNAL(configChanged()), this, SLOT(reconfigureTiling()));
}
TilingLayout::~TilingLayout()
@@ -194,7 +197,7 @@ void TilingLayout::reconfigureTiling()
foreach (Client * c, workspace()->stackingOrder()) {
if (c->rules()->checkTilingOption(0) == 1)
- workspace()->createTile(c);
+ workspace()->tiling()->createTile(c);
}
}
diff --git a/tilinglayout.h b/tiling/tilinglayout.h
similarity index 98%
rename from tilinglayout.h
rename to tiling/tilinglayout.h
index 687d28c776..677db1aa00 100644
--- a/tilinglayout.h
+++ b/tiling/tilinglayout.h
@@ -33,8 +33,9 @@ class Workspace;
class Client;
class Tile;
-class TilingLayout
+class TilingLayout : public QObject
{
+ Q_OBJECT
public:
TilingLayout(Workspace *w);
virtual ~TilingLayout();
@@ -59,7 +60,6 @@ public:
void removeTile(Client *c);
void toggleFloatTile(Client *c);
void swapTiles(Tile *a, Tile *b);
- void reconfigureTiling();
/**
* All tiling layouts do not allow the user to manually
@@ -92,6 +92,9 @@ protected:
virtual void postAddTile(Tile *t);
virtual void preRemoveTile(Tile *t);
+protected Q_SLOTS:
+ void reconfigureTiling();
+
private:
int findTilePos(Client *c) const;
virtual void arrange(QRect wgeom) = 0;
diff --git a/tilinglayoutfactory.cpp b/tilinglayoutfactory.cpp
index 887b0b3ff0..78734e9f90 100644
--- a/tilinglayoutfactory.cpp
+++ b/tilinglayoutfactory.cpp
@@ -26,7 +26,7 @@ along with this program. If not, see .
#include
#include "notifications.h"
-#include "tile.h"
+#include "tiling/tile.h"
#include "client.h"
#include "tilinglayouts/spiral/spiral.h"
diff --git a/tilinglayouts/columns/columns.cpp b/tilinglayouts/columns/columns.cpp
index 0fd33d1a76..d0e1e1b5ec 100644
--- a/tilinglayouts/columns/columns.cpp
+++ b/tilinglayouts/columns/columns.cpp
@@ -21,7 +21,7 @@ along with this program. If not, see .
#include "columns.h"
#include "client.h"
-#include "tile.h"
+#include "tiling/tile.h"
#include
diff --git a/tilinglayouts/columns/columns.h b/tilinglayouts/columns/columns.h
index bcd6f89d77..b8bb1f5469 100644
--- a/tilinglayouts/columns/columns.h
+++ b/tilinglayouts/columns/columns.h
@@ -23,7 +23,7 @@ along with this program. If not, see .
#include
-#include "tilinglayout.h"
+#include "tiling/tilinglayout.h"
namespace KWin
{
diff --git a/tilinglayouts/floating/floating.cpp b/tilinglayouts/floating/floating.cpp
index a0c33e601e..e6623b649c 100644
--- a/tilinglayouts/floating/floating.cpp
+++ b/tilinglayouts/floating/floating.cpp
@@ -20,7 +20,7 @@ along with this program. If not, see .
#include "floating.h"
-#include "tile.h"
+#include "tiling/tile.h"
#include "client.h"
namespace KWin
diff --git a/tilinglayouts/floating/floating.h b/tilinglayouts/floating/floating.h
index c3b40fa3b2..1c007cbfab 100644
--- a/tilinglayouts/floating/floating.h
+++ b/tilinglayouts/floating/floating.h
@@ -24,8 +24,8 @@ along with this program. If not, see .
#include
#include
-#include "tilinglayout.h"
-#include "tile.h"
+#include "tiling/tilinglayout.h"
+#include "tiling/tile.h"
namespace KWin
{
diff --git a/tilinglayouts/spiral/spiral.cpp b/tilinglayouts/spiral/spiral.cpp
index 979e001e52..b70be995e6 100644
--- a/tilinglayouts/spiral/spiral.cpp
+++ b/tilinglayouts/spiral/spiral.cpp
@@ -21,7 +21,7 @@ along with this program. If not, see .
#include "spiral.h"
#include "client.h"
-#include "tile.h"
+#include "tiling/tile.h"
namespace KWin
{
diff --git a/tilinglayouts/spiral/spiral.h b/tilinglayouts/spiral/spiral.h
index f5749f88ef..4621fb06fa 100644
--- a/tilinglayouts/spiral/spiral.h
+++ b/tilinglayouts/spiral/spiral.h
@@ -23,7 +23,7 @@ along with this program. If not, see .
#include
-#include "tilinglayout.h"
+#include "tiling/tilinglayout.h"
namespace KWin
{
diff --git a/useractions.cpp b/useractions.cpp
index 387e4992b7..b6ee9a63e1 100644
--- a/useractions.cpp
+++ b/useractions.cpp
@@ -30,8 +30,11 @@ along with this program. If not, see .
#include "client.h"
#include "workspace.h"
#include "effects.h"
-#include "tile.h"
-#include "tilinglayout.h"
+#ifdef KWIN_BUILD_TILING
+#include "tiling/tile.h"
+#include "tiling/tilinglayout.h"
+#include "tiling/tiling.h"
+#endif
#include "kactivityinfo.h"
@@ -197,14 +200,16 @@ QMenu* Workspace::clientPopup()
mTilingStateOpAction = popup->addAction(i18nc("When in tiling mode, toggle's the window's floating/tiled state", "&Float Window"));
// then hide it
mTilingStateOpAction->setVisible(false);
+#ifdef KWIN_BUILD_TILING
// actions for window tiling
- if (tilingEnabled()) {
+ if (m_tiling->isEnabled()) {
kaction = qobject_cast(keys->action("Toggle Floating"));
mTilingStateOpAction->setCheckable(true);
mTilingStateOpAction->setData(Options::ToggleClientTiledStateOp);
if (kaction != 0)
mTilingStateOpAction->setShortcut(kaction->globalShortcut().primary());
}
+#endif
popup->addSeparator();
@@ -289,16 +294,17 @@ void Workspace::clientPopupAboutToShow()
mMinimizeOpAction->setEnabled(active_popup_client->isMinimizable());
mCloseOpAction->setEnabled(active_popup_client->isCloseable());
- if (tilingEnabled()) {
+#ifdef KWIN_BUILD_TILING
+ if (m_tiling->isEnabled()) {
int desktop = active_popup_client->desktop();
- if (tilingLayouts.value(desktop)) {
- Tile *t = tilingLayouts[desktop]->findTile(active_popup_client);
+ if (m_tiling->tilingLayouts().value(desktop)) {
+ Tile *t = m_tiling->tilingLayouts()[desktop]->findTile(active_popup_client);
if (t)
mTilingStateOpAction->setChecked(t->floating());
}
}
- mTilingStateOpAction->setVisible(tilingEnabled());
-
+ mTilingStateOpAction->setVisible(m_tiling->isEnabled());
+#endif
delete switch_to_tab_popup;
switch_to_tab_popup = 0;
delete add_tabs_popup;
@@ -563,6 +569,11 @@ void Workspace::initShortcuts()
if (tab_box) {
tab_box->initShortcuts(actionCollection);
}
+#endif
+#ifdef KWIN_BUILD_TILING
+ if (m_tiling) {
+ m_tiling->initShortcuts(actionCollection);
+ }
#endif
discardPopup(); // so that it's recreated next time
}
@@ -659,16 +670,16 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op)
{
if (!c)
return;
-
+#ifdef KWIN_BUILD_TILING
// Allows us to float a window when it is maximized, if it is tiled.
- if (tilingEnabled()
+ if (m_tiling->isEnabled()
&& (op == Options::MaximizeOp
|| op == Options::HMaximizeOp
|| op == Options::VMaximizeOp
|| op == Options::RestoreOp)) {
- notifyTilingWindowMaximized(c, op);
+ m_tiling->notifyTilingWindowMaximized(c, op);
}
-
+#endif
if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp)
QCursor::setPos(c->geometry().center());
if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp)
@@ -779,10 +790,12 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op)
case Options::CloseClientGroupOp:
c->clientGroup()->closeAll();
case Options::ToggleClientTiledStateOp: {
+#ifdef KWIN_BUILD_TILING
int desktop = c->desktop();
- if (tilingLayouts.value(desktop)) {
- tilingLayouts[desktop]->toggleFloatTile(c);
+ if (m_tiling->tilingLayouts().value(desktop)) {
+ m_tiling->tilingLayouts()[desktop]->toggleFloatTile(c);
}
+#endif
}
}
}
diff --git a/workspace.cpp b/workspace.cpp
index b9556681b2..74a854e5ef 100644
--- a/workspace.cpp
+++ b/workspace.cpp
@@ -44,7 +44,6 @@ along with this program. If not, see .
#include
#include "client.h"
-#include "tile.h"
#ifdef KWIN_BUILD_TABBOX
#include "tabbox.h"
#endif
@@ -62,8 +61,11 @@ along with this program. If not, see .
#include "deleted.h"
#include "effects.h"
#include "overlaywindow.h"
-#include "tilinglayout.h"
-
+#ifdef KWIN_BUILD_TILING
+#include "tiling/tile.h"
+#include "tiling/tilinglayout.h"
+#include "tiling/tiling.h"
+#endif
#ifdef KWIN_BUILD_SCRIPTING
#include "scripting/scripting.h"
#endif
@@ -107,7 +109,6 @@ Workspace::Workspace(bool restore)
, desktopGridSize_(1, 2) // Default to two rows
, desktopGrid_(new int[2])
, currentDesktop_(0)
- , tilingEnabled_(false)
// Unsorted
, active_popup(NULL)
, active_popup_client(NULL)
@@ -235,11 +236,16 @@ Workspace::Workspace(bool restore)
);
client_keys = new KActionCollection(this);
- initShortcuts();
+
#ifdef KWIN_BUILD_DESKTOPCHANGEOSD
desktop_change_osd = new DesktopChangeOSD(this);
#endif
m_outline = new Outline();
+#ifdef KWIN_BUILD_TILING
+ m_tiling = new Tiling(this);
+#endif
+
+ initShortcuts();
init();
@@ -487,8 +493,10 @@ void Workspace::init()
if (new_active_client != NULL)
activateClient(new_active_client);
+#ifdef KWIN_BUILD_TILING
// Enable/disable tiling
- setTilingEnabled(options->tilingOn);
+ m_tiling->setEnabled(options->tilingOn);
+#endif
// SELI TODO: This won't work with unreasonable focus policies,
// and maybe in rare cases also if the selected client doesn't
@@ -502,6 +510,9 @@ Workspace::~Workspace()
{
finishCompositing();
blockStackingUpdates(true);
+#ifdef KWIN_BUILD_TILING
+ delete m_tiling;
+#endif
// TODO: grabXServer();
@@ -562,9 +573,8 @@ Client* Workspace::createClient(Window w, bool is_mapped)
}
addClient(c, Allowed);
- tilingLayouts.resize(numberOfDesktops() + 1);
+ m_tiling->createTile(c);
- createTile(c);
return c;
}
@@ -668,9 +678,6 @@ void Workspace::removeClient(Client* c, allowed_t)
#endif
Q_ASSERT(clients.contains(c) || desktops.contains(c));
- if (tilingEnabled() && tilingLayouts.value(c->desktop())) {
- removeTile(c);
- }
// TODO: if marked client is removed, notify the marked list
clients.removeAll(c);
desktops.removeAll(c);
@@ -1027,13 +1034,11 @@ void Workspace::slotReconfigure()
}
}
- setTilingEnabled(options->tilingOn);
- foreach (TilingLayout * layout, tilingLayouts) {
- if (layout)
- layout->reconfigureTiling();
- }
+#ifdef KWIN_BUILD_TILING
+ m_tiling->setEnabled(options->tilingOn);
// just so that we reset windows in the right manner, 'activate' the current active window
- notifyTilingWindowActivated(activeClient());
+ m_tiling->notifyTilingWindowActivated(activeClient());
+#endif
if (hasDecorationPlugin()) {
rootInfo->setSupported(NET::WM2FrameOverlap, mgr->factory()->supports(AbilityExtendIntoClientArea));
} else {
@@ -1296,9 +1301,13 @@ bool Workspace::setCurrentDesktop(int new_desktop)
if (movingClient && !movingClient->isOnDesktop(new_desktop)) {
int old_desktop = movingClient->desktop();
movingClient->setDesktop(new_desktop);
- if (tilingEnabled()) {
- notifyTilingWindowDesktopChanged(movingClient, old_desktop);
+#ifdef KWIN_BUILD_TILING
+ if (m_tiling->isEnabled()) {
+ m_tiling->notifyTilingWindowDesktopChanged(movingClient, old_desktop);
}
+#else
+ Q_UNUSED(old_desktop)
+#endif
}
for (int i = stacking_order.size() - 1; i >= 0 ; --i)
@@ -1577,8 +1586,6 @@ void Workspace::setNumberOfDesktops(int n)
for (int i = 0; i < int(desktop_focus_chain.size()); i++)
desktop_focus_chain[i] = i + 1;
- tilingLayouts.resize(numberOfDesktops() + 1);
-
saveDesktopSettings();
emit numberDesktopsChanged(old_number_of_desktops);
}
@@ -1611,7 +1618,9 @@ void Workspace::sendClientToDesktop(Client* c, int desk, bool dont_activate)
} else
raiseClient(c);
- notifyTilingWindowDesktopChanged(c, old_desktop);
+#ifdef KWIN_BUILD_TILING
+ m_tiling->notifyTilingWindowDesktopChanged(c, old_desktop);
+#endif
ClientList transients_stacking_order = ensureStackingOrder(c->transients());
for (ClientList::ConstIterator it = transients_stacking_order.constBegin();
@@ -2151,6 +2160,57 @@ TabBox::TabBox* Workspace::tabBox() const
}
#endif
+#ifdef KWIN_BUILD_TILING
+Tiling* Workspace::tiling()
+{
+ return m_tiling;
+}
+#endif
+
+/*
+ * Called from D-BUS
+ */
+void Workspace::toggleTiling()
+{
+#ifdef KWIN_BUILD_TILING
+ if (m_tiling) {
+ m_tiling->slotToggleTiling();
+ }
+#endif
+}
+
+/*
+ * Called from D-BUS
+ */
+void Workspace::nextTileLayout()
+{
+#ifdef KWIN_BUILD_TILING
+ if (m_tiling) {
+ m_tiling->slotNextTileLayout();
+ }
+#endif
+}
+
+/*
+ * Called from D-BUS
+ */
+void Workspace::previousTileLayout()
+{
+#ifdef KWIN_BUILD_TILING
+ if (m_tiling) {
+ m_tiling->slotPreviousTileLayout();
+ }
+#endif
+}
+
+void Workspace::dumpTiles() const {
+#ifdef KWIN_BUILD_TILING
+ if (m_tiling) {
+ m_tiling->dumpTiles();
+ }
+#endif
+}
+
} // namespace
#include "workspace.moc"
diff --git a/workspace.h b/workspace.h
index 79c1e2d691..492d1ca33b 100644
--- a/workspace.h
+++ b/workspace.h
@@ -73,8 +73,11 @@ class TabBox;
#endif
class Client;
+#ifdef KWIN_BUILD_TILING
class Tile;
+class Tiling;
class TilingLayout;
+#endif
class ClientGroup;
#ifdef KWIN_BUILD_DESKTOPCHANGEOSD
class DesktopChangeOSD;
@@ -197,31 +200,9 @@ public:
return unmanaged;
}
- //-------------------------------------------------
- // Tiling
-public:
- bool tilingEnabled() const;
- void setTilingEnabled(bool tiling);
- bool tileable(Client *c);
- void createTile(Client *c);
- // updates geometry of tiles on all desktops,
- // this rearranges the tiles.
- void updateAllTiles();
-
- // The notification functions are called from
- // various points in existing code so that
- // tiling can take any action if required.
- // They are defined in tiling.cpp
- void notifyTilingWindowResize(Client *c, const QRect &moveResizeGeom, const QRect &orig);
- void notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, const QRect &orig);
- void notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled);
- void notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled);
- void notifyTilingWindowDesktopChanged(Client *c, int old_desktop);
- void notifyTilingWindowActivated(Client *c);
- void notifyTilingWindowMinimizeToggled(Client *c);
- void notifyTilingWindowMaximized(Client *c, WindowOperation op);
-
- Position supportedTilingResizeMode(Client *c, Position currentMode);
+#ifdef KWIN_BUILD_TILING
+ Tiling* tiling();
+#endif
Outline* outline();
#ifdef KWIN_BUILD_SCREENEDGES
@@ -329,13 +310,9 @@ private:
KActivityController activityController_;
- bool tilingEnabled_;
- // Each tilingLayout is for one virtual desktop.
- // The length is always one more than the number of
- // virtual desktops so that we can quickly index them
- // without having to remember to subtract one.
- QVector tilingLayouts;
-
+#ifdef KWIN_BUILD_TILING
+ Tiling* m_tiling;
+#endif
Outline* m_outline;
#ifdef KWIN_BUILD_SCREENEDGES
ScreenEdge m_screenEdge;
@@ -640,25 +617,6 @@ public slots:
void suspendCompositing();
void suspendCompositing(bool suspend);
- // user actions, usually bound to shortcuts
- // and also provided through the D-BUS interface.
- void slotToggleTiling();
- void slotToggleFloating();
- void slotNextTileLayout();
- void slotPreviousTileLayout();
-
- // Changes the focused client
- void slotFocusTileLeft();
- void slotFocusTileRight();
- void slotFocusTileTop();
- void slotFocusTileBottom();
- // swaps active and adjacent client.
- void slotMoveTileLeft();
- void slotMoveTileRight();
- void slotMoveTileTop();
- void slotMoveTileBottom();
- void belowCursor();
-
// NOTE: debug method
void dumpTiles() const;
@@ -805,16 +763,6 @@ private:
static NET::WindowType txtToWindowType(const char* txt);
static bool sessionInfoWindowTypeMatch(Client* c, SessionInfo* info);
- // try to get a decent tile, either the one with
- // focus or the one below the mouse.
- Tile* getNiceTile() const;
- void removeTile(Client *c);
- // int, and not Tile::Direction because
- // we are using a forward declaration for Tile
- Tile* findAdjacentTile(Tile *ref, int d);
- void focusTile(int d);
- void moveTile(int d);
-
Client* active_client;
Client* last_active_client;
Client* most_recently_raised; // Used ONLY by raiseOrLowerClient()
@@ -1263,30 +1211,6 @@ inline void Workspace::removeClientGroup(ClientGroup* group)
clientGroups.removeAll(group);
}
-/*
- * Called from D-BUS
- */
-inline void Workspace::toggleTiling()
-{
- slotToggleTiling();
-}
-
-/*
- * Called from D-BUS
- */
-inline void Workspace::nextTileLayout()
-{
- slotNextTileLayout();
-}
-
-/*
- * Called from D-BUS
- */
-inline void Workspace::previousTileLayout()
-{
- slotPreviousTileLayout();
-}
-
} // namespace
#endif