Refactoring Tiling

This initial commit introduces a new class Tiling. It is provided by
the files tiling/tiling.h and tiling/tiling.cpp. It covers all the
Tiling functionality which was provided by Workspace. In this initial
commit, all the functions were just moved and adjusted.
A  new member variable m_tiling is introduced to Workspace, which
makes the new class Tiling accessible from Workspace.
The Tiling pointer is created in the constructor and deleted in
the deconstructor. Also a getter method tiling() is provided.
All calls from other classes are updated to use the methods in class
Tiling now.
icc-effect-5.14.5
Arthur Arlt 2011-07-13 18:48:56 +02:00
parent 6db74c8d66
commit 3634525613
11 changed files with 283 additions and 192 deletions

View File

@ -42,6 +42,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "group.h" #include "group.h"
#include "rules.h" #include "rules.h"
#include <QX11Info> #include <QX11Info>
#include "tiling/tiling.h"
namespace KWin namespace KWin
{ {
@ -263,8 +264,8 @@ void Workspace::setActiveClient(Client* c, allowed_t)
active_client->sl_activated(); active_client->sl_activated();
} }
if (tilingEnabled()) if (m_tiling->tilingEnabled())
notifyTilingWindowActivated(active_client); m_tiling->notifyTilingWindowActivated(active_client);
--set_active_client_recursion; --set_active_client_recursion;
} }

View File

@ -47,6 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "notifications.h" #include "notifications.h"
#include "rules.h" #include "rules.h"
#include "shadow.h" #include "shadow.h"
#include "tiling/tiling.h"
#include "deleted.h" #include "deleted.h"
#include "paintredirector.h" #include "paintredirector.h"
#ifdef KWIN_BUILD_TABBOX #ifdef KWIN_BUILD_TABBOX
@ -951,7 +952,7 @@ void Client::minimize(bool avoid_animation)
emit clientMinimized(this, !avoid_animation); emit clientMinimized(this, !avoid_animation);
// when tiling, request a rearrangement // when tiling, request a rearrangement
workspace()->notifyTilingWindowMinimizeToggled(this); workspace()->tiling()->notifyTilingWindowMinimizeToggled(this);
// Update states of all other windows in this group // Update states of all other windows in this group
if (clientGroup()) if (clientGroup())
@ -978,11 +979,11 @@ void Client::unminimize(bool avoid_animation)
updateAllowedActions(); updateAllowedActions();
workspace()->updateMinimizedOfTransients(this); workspace()->updateMinimizedOfTransients(this);
updateWindowRules(); updateWindowRules();
workspace()->updateAllTiles(); workspace()->tiling()->updateAllTiles();
emit clientUnminimized(this, !avoid_animation); emit clientUnminimized(this, !avoid_animation);
// when tiling, request a rearrangement // when tiling, request a rearrangement
workspace()->notifyTilingWindowMinimizeToggled(this); workspace()->tiling()->notifyTilingWindowMinimizeToggled(this);
// Update states of all other windows in this group // Update states of all other windows in this group
if (clientGroup()) if (clientGroup())

View File

@ -50,6 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kephal/screens.h> #include <kephal/screens.h>
#include <KDE/KGlobalSettings> #include <KDE/KGlobalSettings>
#include "outline.h" #include "outline.h"
#include "tiling/tiling.h"
namespace KWin namespace KWin
{ {
@ -2032,7 +2033,7 @@ void Client::move(int x, int y, ForceGeometry_t force)
workspace()->checkActiveScreen(this); workspace()->checkActiveScreen(this);
workspace()->updateStackingOrder(); workspace()->updateStackingOrder();
workspace()->checkUnredirect(); workspace()->checkUnredirect();
workspace()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom); workspace()->tiling()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom);
// client itself is not damaged // client itself is not damaged
const QRect deco_rect = decorationRect().translated(geom.x(), geom.y()); const QRect deco_rect = decorationRect().translated(geom.x(), geom.y());
addWorkspaceRepaint(deco_rect_before_block); addWorkspaceRepaint(deco_rect_before_block);
@ -2590,11 +2591,11 @@ void Client::finishMoveResize(bool cancel)
leaveMoveResize(); leaveMoveResize();
if (workspace()->tilingEnabled()) { if (workspace()->tiling()->tilingEnabled()) {
if (wasResize) if (wasResize)
workspace()->notifyTilingWindowResizeDone(this, moveResizeGeom, initialMoveResizeGeom, cancel); workspace()->tiling()->notifyTilingWindowResizeDone(this, moveResizeGeom, initialMoveResizeGeom, cancel);
else if (wasMove) else if (wasMove)
workspace()->notifyTilingWindowMoveDone(this, moveResizeGeom, initialMoveResizeGeom, cancel); workspace()->tiling()->notifyTilingWindowMoveDone(this, moveResizeGeom, initialMoveResizeGeom, cancel);
} else { } else {
if (cancel) if (cancel)
setGeometry(initialMoveResizeGeom); setGeometry(initialMoveResizeGeom);
@ -2763,8 +2764,8 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
bool update = false; bool update = false;
if (isResize()) { if (isResize()) {
// query layout for supported resize mode // query layout for supported resize mode
if (workspace()->tilingEnabled()) { if (workspace()->tiling()->tilingEnabled()) {
mode = workspace()->supportedTilingResizeMode(this, mode); mode = workspace()->tiling()->supportedTilingResizeMode(this, mode);
} }
// first resize (without checking constrains), then snap, then check bounds, then check constrains // first resize (without checking constrains), then snap, then check bounds, then check constrains
QRect orig = initialMoveResizeGeom; QRect orig = initialMoveResizeGeom;
@ -2801,7 +2802,7 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
case PositionCenter: case PositionCenter:
// exception for tiling // exception for tiling
// Center means no resizing allowed // Center means no resizing allowed
if (workspace()->tilingEnabled()) { if (workspace()->tiling()->tilingEnabled()) {
finishMoveResize(false); finishMoveResize(false);
buttonDown = false; buttonDown = false;
return; return;
@ -2810,7 +2811,7 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
abort(); abort();
break; break;
} }
workspace()->notifyTilingWindowResize(this, moveResizeGeom, initialMoveResizeGeom); workspace()->tiling()->notifyTilingWindowResize(this, moveResizeGeom, initialMoveResizeGeom);
// adjust new size to snap to other windows/borders // adjust new size to snap to other windows/borders
moveResizeGeom = workspace()->adjustClientSize(this, moveResizeGeom, mode); moveResizeGeom = workspace()->adjustClientSize(this, moveResizeGeom, mode);
@ -2968,7 +2969,7 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
performMoveResize(); performMoveResize();
if (isMove()) { if (isMove()) {
workspace()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom); workspace()->tiling()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom);
#ifdef KWIN_BUILD_SCREENEDGES #ifdef KWIN_BUILD_SCREENEDGES
workspace()->screenEdge()->check(globalPos, xTime()); workspace()->screenEdge()->check(globalPos, xTime());
#endif #endif
@ -2986,7 +2987,7 @@ void Client::performMoveResize()
sendSyncRequest(); sendSyncRequest();
} }
#endif #endif
if (!workspace()->tilingEnabled()) if (!workspace()->tiling()->tilingEnabled())
setGeometry(moveResizeGeom); setGeometry(moveResizeGeom);
positionGeometryTip(); positionGeometryTip();
emit clientStepUserMovedResized(this, moveResizeGeom); emit clientStepUserMovedResized(this, moveResizeGeom);

9
sm.cpp
View File

@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QSocketNotifier> #include <QSocketNotifier>
#include <QSessionManager> #include <QSessionManager>
#include <kdebug.h> #include <kdebug.h>
#include "tiling/tiling.h"
namespace KWin namespace KWin
{ {
@ -84,10 +85,10 @@ void Workspace::storeSession(KConfig* config, SMSavePhase phase)
int active_client = -1; int active_client = -1;
if (phase == SMSavePhase2 || phase == SMSavePhase2Full) { if (phase == SMSavePhase2 || phase == SMSavePhase2Full) {
cg.writeEntry("tiling", tilingEnabled()); cg.writeEntry("tiling", m_tiling->tilingEnabled());
if (tilingEnabled()) { if (m_tiling->tilingEnabled()) {
kDebug(1212) << "Tiling was ON"; kDebug(1212) << "Tiling was ON";
setTilingEnabled(false); m_tiling->setTilingEnabled(false);
} }
} }
@ -273,7 +274,7 @@ void Workspace::loadSessionInfo()
session.clear(); session.clear();
KConfigGroup cg(kapp->sessionConfig(), "Session"); KConfigGroup cg(kapp->sessionConfig(), "Session");
setTilingEnabled(cg.readEntry("tiling", false)); m_tiling->setTilingEnabled(cg.readEntry("tiling", false));
addSessionInfo(cg); addSessionInfo(cg);
} }

View File

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "client.h" #include "client.h"
#include "workspace.h" #include "workspace.h"
#include "tiling/tiling.h"
namespace KWin namespace KWin
{ {
@ -95,7 +96,7 @@ void Tile::floatTile()
restorePreviousGeometry(); restorePreviousGeometry();
commit(); commit();
client()->workspace()->notifyTilingWindowActivated(client()); client()->workspace()->tiling()->notifyTilingWindowActivated(client());
// TODO: notify layout manager // TODO: notify layout manager
} }

View File

@ -3,6 +3,7 @@
This file is part of the KDE project. This file is part of the KDE project.
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com> Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
Copyright (C) 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -18,30 +19,36 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/ *********************************************************************/
// all the tiling related code that is extensions to existing KWin classes #include <tiling/tiling.h>
// Includes Workspace for now
#include "client.h"
#include "workspace.h"
#include "tile.h"
#include "tilinglayout.h"
#include "tilinglayoutfactory.h"
#include <knotification.h>
#include <klocale.h> #include <klocale.h>
#include <knotification.h>
#include <kwindowinfo.h> #include <kwindowinfo.h>
#include <kwindowsystem.h> #include <kwindowsystem.h>
#include "tile.h"
#include "tilinglayout.h"
#include "tilinglayoutfactory.h"
#include "workspace.h"
namespace KWin namespace KWin {
Tiling::Tiling(KWin::Workspace* w)
: QObject(w)
, m_workspace(w)
, tilingEnabled_(false)
{ {
}
bool Workspace::tilingEnabled() const Tiling::~Tiling()
{
}
bool Tiling::tilingEnabled() const
{ {
return tilingEnabled_; return tilingEnabled_;
} }
void Workspace::setTilingEnabled(bool tiling) void Tiling::setTilingEnabled(bool tiling)
{ {
if (tilingEnabled() == tiling) return; if (tilingEnabled() == tiling) return;
@ -56,8 +63,8 @@ void Workspace::setTilingEnabled(bool tiling)
options->tilingRaisePolicy = config.readEntry("TilingRaisePolicy", 0); options->tilingRaisePolicy = config.readEntry("TilingRaisePolicy", 0);
if (tilingEnabled_) { if (tilingEnabled_) {
tilingLayouts.resize(numberOfDesktops() + 1); tilingLayouts.resize(Workspace::self()->numberOfDesktops() + 1);
foreach (Client * c, stackingOrder()) { foreach (Client * c, Workspace::self()->stackingOrder()) {
createTile(c); createTile(c);
} }
} else { } else {
@ -66,7 +73,7 @@ void Workspace::setTilingEnabled(bool tiling)
} }
} }
void Workspace::slotToggleTiling() void Tiling::slotToggleTiling()
{ {
if (tilingEnabled()) { if (tilingEnabled()) {
setTilingEnabled(false); setTilingEnabled(false);
@ -79,7 +86,7 @@ void Workspace::slotToggleTiling()
} }
} }
void Workspace::createTile(Client *c) void Tiling::createTile(Client* c)
{ {
if (c == NULL) if (c == NULL)
return; return;
@ -90,28 +97,27 @@ void Workspace::createTile(Client *c)
if (!tilingEnabled() || !tileable(c)) if (!tilingEnabled() || !tileable(c))
return; return;
Tile *t = new Tile(c, clientArea(PlacementArea, c)); Tile *t = new Tile(c, Workspace::self()->clientArea(PlacementArea, c));
if (!tileable(c)) { if (!tileable(c)) {
kDebug(1212) << c->caption() << "is not tileable"; kDebug(1212) << c->caption() << "is not tileable";
t->floatTile(); t->floatTile();
} }
if (!tilingLayouts.value(c->desktop())) { if (!tilingLayouts.value(c->desktop())) {
tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, this); tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, m_workspace);
} }
tilingLayouts[c->desktop()]->addTile(t); tilingLayouts[c->desktop()]->addTile(t);
tilingLayouts[c->desktop()]->commit(); tilingLayouts[c->desktop()]->commit();
} }
void Workspace::removeTile(Client *c) void Tiling::removeTile(Client *c)
{ {
if (tilingLayouts[ c->desktop()]) if (tilingLayouts[ c->desktop()])
tilingLayouts[ c->desktop()]->removeTile(c); tilingLayouts[ c->desktop()]->removeTile(c);
} }
bool Workspace::tileable(Client *c) bool Tiling::tileable(Client* c)
{ {
kDebug(1212) << c->caption(); kDebug(1212) << c->caption();
KWindowInfo info = KWindowSystem::windowInfo(c->window(), -1U, NET::WM2WindowClass); KWindowInfo info = KWindowSystem::windowInfo(c->window(), -1U, NET::WM2WindowClass);
kDebug(1212) << "WINDOW CLASS IS " << info.windowClassClass(); kDebug(1212) << "WINDOW CLASS IS " << info.windowClassClass();
@ -134,21 +140,21 @@ bool Workspace::tileable(Client *c)
return true; return true;
} }
void Workspace::belowCursor() void Tiling::belowCursor()
{ {
// TODO // TODO
} }
Tile* Workspace::getNiceTile() const Tile* Tiling::getNiceTile() const
{ {
if (!tilingEnabled()) return NULL; if (!tilingEnabled()) return NULL;
if (!tilingLayouts.value(activeClient()->desktop())) return NULL; if (!tilingLayouts.value(m_workspace->activeClient()->desktop())) return NULL;
return tilingLayouts[ activeClient()->desktop()]->findTile(activeClient()); return tilingLayouts[ m_workspace->activeClient()->desktop()]->findTile(m_workspace->activeClient());
// TODO // TODO
} }
void Workspace::updateAllTiles() void Tiling::updateAllTiles()
{ {
foreach (TilingLayout * t, tilingLayouts) { foreach (TilingLayout * t, tilingLayouts) {
if (!t) continue; if (!t) continue;
@ -159,14 +165,14 @@ void Workspace::updateAllTiles()
/* /*
* Resize the neighbouring clients to close any gaps * Resize the neighbouring clients to close any gaps
*/ */
void Workspace::notifyTilingWindowResize(Client *c, const QRect &moveResizeGeom, const QRect &orig) void Tiling::notifyTilingWindowResize(Client *c, const QRect &moveResizeGeom, const QRect &orig)
{ {
if (tilingLayouts.value(c->desktop()) == NULL) if (tilingLayouts.value(c->desktop()) == NULL)
return; return;
tilingLayouts[ c->desktop()]->clientResized(c, moveResizeGeom, orig); tilingLayouts[ c->desktop()]->clientResized(c, moveResizeGeom, orig);
} }
void Workspace::notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, const QRect &orig) void Tiling::notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, const QRect &orig)
{ {
if (tilingLayouts.value(c->desktop()) == NULL) { if (tilingLayouts.value(c->desktop()) == NULL) {
return; return;
@ -175,7 +181,7 @@ void Workspace::notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, c
updateAllTiles(); updateAllTiles();
} }
void Workspace::notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled) void Tiling::notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled)
{ {
if (canceled) if (canceled)
notifyTilingWindowResize(c, orig, moveResizeGeom); notifyTilingWindowResize(c, orig, moveResizeGeom);
@ -183,7 +189,7 @@ void Workspace::notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeG
notifyTilingWindowResize(c, moveResizeGeom, orig); notifyTilingWindowResize(c, moveResizeGeom, orig);
} }
void Workspace::notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled) void Tiling::notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeom, const QRect &orig, bool canceled)
{ {
if (canceled) if (canceled)
notifyTilingWindowMove(c, orig, moveResizeGeom); notifyTilingWindowMove(c, orig, moveResizeGeom);
@ -191,9 +197,9 @@ void Workspace::notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeo
notifyTilingWindowMove(c, moveResizeGeom, orig); notifyTilingWindowMove(c, moveResizeGeom, orig);
} }
void Workspace::notifyTilingWindowDesktopChanged(Client *c, int old_desktop) void Tiling::notifyTilingWindowDesktopChanged(Client *c, int old_desktop)
{ {
if (c->desktop() < 1 || c->desktop() > numberOfDesktops()) if (c->desktop() < 1 || c->desktop() > m_workspace->numberOfDesktops())
return; return;
if (tilingLayouts.value(old_desktop)) { if (tilingLayouts.value(old_desktop)) {
@ -201,7 +207,7 @@ void Workspace::notifyTilingWindowDesktopChanged(Client *c, int old_desktop)
// TODO: copied from createTile(), move this into separate method? // TODO: copied from createTile(), move this into separate method?
if (!tilingLayouts.value(c->desktop())) { if (!tilingLayouts.value(c->desktop())) {
tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, this); tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, m_workspace);
} }
if (t) if (t)
@ -215,7 +221,7 @@ void Workspace::notifyTilingWindowDesktopChanged(Client *c, int old_desktop)
/* /*
* Implements the 3 raising modes in Window Behaviour -> Advanced * Implements the 3 raising modes in Window Behaviour -> Advanced
*/ */
void Workspace::notifyTilingWindowActivated(Client *c) void Tiling::notifyTilingWindowActivated(Client *c)
{ {
if (c == NULL) if (c == NULL)
return; return;
@ -226,7 +232,7 @@ void Workspace::notifyTilingWindowActivated(Client *c)
if (tilingLayouts.value(c->desktop())) { if (tilingLayouts.value(c->desktop())) {
QList<Tile *> tiles = tilingLayouts[ c->desktop()]->tiles(); QList<Tile *> tiles = tilingLayouts[ c->desktop()]->tiles();
StackingUpdatesBlocker blocker(this); StackingUpdatesBlocker blocker(m_workspace);
Tile *tile_to_raise = tilingLayouts[ c->desktop()]->findTile(c); Tile *tile_to_raise = tilingLayouts[ c->desktop()]->findTile(c);
@ -243,24 +249,24 @@ void Workspace::notifyTilingWindowActivated(Client *c)
foreach (Tile * t, tiles) { foreach (Tile * t, tiles) {
if (t->floating() == raise_floating && t != tile_to_raise) if (t->floating() == raise_floating && t != tile_to_raise)
raiseClient(t->client()); m_workspace->raiseClient(t->client());
} }
// raise the current tile last so that it ends up on top // raise the current tile last so that it ends up on top
// but only if it supposed to be raised, required to support tilingRaisePolicy // 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(); kDebug(1212) << "Raise floating? " << raise_floating << "to raise is floating?" << tile_to_raise->floating();
if (tile_to_raise->floating() == raise_floating) if (tile_to_raise->floating() == raise_floating)
raiseClient(tile_to_raise->client()); m_workspace->raiseClient(tile_to_raise->client());
} }
} }
void Workspace::notifyTilingWindowMinimizeToggled(Client *c) void Tiling::notifyTilingWindowMinimizeToggled(Client *c)
{ {
if (tilingLayouts.value(c->desktop())) { if (tilingLayouts.value(c->desktop())) {
tilingLayouts[ c->desktop()]->clientMinimizeToggled(c); tilingLayouts[ c->desktop()]->clientMinimizeToggled(c);
} }
} }
void Workspace::notifyTilingWindowMaximized(Client *c, Options::WindowOperation op) void Tiling::notifyTilingWindowMaximized(Client *c, Options::WindowOperation op)
{ {
if (tilingLayouts.value(c->desktop())) { if (tilingLayouts.value(c->desktop())) {
Tile *t = tilingLayouts[ c->desktop()]->findTile(c); Tile *t = tilingLayouts[ c->desktop()]->findTile(c);
@ -291,7 +297,7 @@ void Workspace::notifyTilingWindowMaximized(Client *c, Options::WindowOperation
} }
} }
Tile* Workspace::findAdjacentTile(Tile *ref, int d) Tile* Tiling::findAdjacentTile(Tile *ref, int d)
{ {
QRect reference = ref->geometry(); QRect reference = ref->geometry();
QPoint origin = reference.center(); QPoint origin = reference.center();
@ -346,17 +352,17 @@ Tile* Workspace::findAdjacentTile(Tile *ref, int d)
return closest; return closest;
} }
void Workspace::focusTile(int d) void Tiling::focusTile(int d)
{ {
Tile *t = getNiceTile(); Tile *t = getNiceTile();
if (t) { if (t) {
Tile *adj = findAdjacentTile(t, d); Tile *adj = findAdjacentTile(t, d);
if (adj) if (adj)
activateClient(adj->client()); m_workspace->activateClient(adj->client());
} }
} }
void Workspace::moveTile(int d) void Tiling::moveTile(int d)
{ {
Tile *t = getNiceTile(); Tile *t = getNiceTile();
if (t) { if (t) {
@ -366,75 +372,75 @@ void Workspace::moveTile(int d)
} }
} }
void Workspace::slotFocusTileLeft() void Tiling::slotFocusTileLeft()
{ {
focusTile(Tile::Left); focusTile(Tile::Left);
} }
void Workspace::slotFocusTileRight() void Tiling::slotFocusTileRight()
{ {
focusTile(Tile::Right); focusTile(Tile::Right);
} }
void Workspace::slotFocusTileTop() void Tiling::slotFocusTileTop()
{ {
focusTile(Tile::Top); focusTile(Tile::Top);
} }
void Workspace::slotFocusTileBottom() void Tiling::slotFocusTileBottom()
{ {
focusTile(Tile::Bottom); focusTile(Tile::Bottom);
} }
void Workspace::slotMoveTileLeft() void Tiling::slotMoveTileLeft()
{ {
moveTile(Tile::Left); moveTile(Tile::Left);
} }
void Workspace::slotMoveTileRight() void Tiling::slotMoveTileRight()
{ {
moveTile(Tile::Right); moveTile(Tile::Right);
} }
void Workspace::slotMoveTileTop() void Tiling::slotMoveTileTop()
{ {
moveTile(Tile::Top); moveTile(Tile::Top);
} }
void Workspace::slotMoveTileBottom() void Tiling::slotMoveTileBottom()
{ {
moveTile(Tile::Bottom); moveTile(Tile::Bottom);
} }
void Workspace::slotToggleFloating() void Tiling::slotToggleFloating()
{ {
Client *c = activeClient(); Client *c = m_workspace->activeClient();
if (tilingLayouts.value(c->desktop())) { if (tilingLayouts.value(c->desktop())) {
tilingLayouts[ c->desktop()]->toggleFloatTile(c); tilingLayouts[ c->desktop()]->toggleFloatTile(c);
} }
} }
void Workspace::slotNextTileLayout() void Tiling::slotNextTileLayout()
{ {
if (tilingLayouts.value(currentDesktop())) { if (tilingLayouts.value(m_workspace->currentDesktop())) {
tilingLayouts.replace(currentDesktop(), TilingLayoutFactory::nextLayout(tilingLayouts[currentDesktop()])); tilingLayouts.replace(m_workspace->currentDesktop(), TilingLayoutFactory::nextLayout(tilingLayouts[m_workspace->currentDesktop()]));
tilingLayouts[currentDesktop()]->commit(); tilingLayouts[m_workspace->currentDesktop()]->commit();
} }
} }
void Workspace::slotPreviousTileLayout() void Tiling::slotPreviousTileLayout()
{ {
if (tilingLayouts.value(currentDesktop())) { if (tilingLayouts.value(m_workspace->currentDesktop())) {
tilingLayouts.replace(currentDesktop(), TilingLayoutFactory::previousLayout(tilingLayouts[currentDesktop()])); tilingLayouts.replace(m_workspace->currentDesktop(), TilingLayoutFactory::previousLayout(tilingLayouts[m_workspace->currentDesktop()]));
tilingLayouts[currentDesktop()]->commit(); tilingLayouts[m_workspace->currentDesktop()]->commit();
} }
} }
KDecorationDefines::Position Workspace::supportedTilingResizeMode(Client *c, KDecorationDefines::Position currentMode) KDecorationDefines::Position Tiling::supportedTilingResizeMode(Client *c, KDecorationDefines::Position currentMode)
{ {
if (tilingLayouts.value(c->desktop())) { if (tilingLayouts.value(c->desktop())) {
return tilingLayouts[c->desktop()]->resizeMode(c, currentMode); return tilingLayouts[c->desktop()]->resizeMode(c, currentMode);
@ -442,7 +448,7 @@ KDecorationDefines::Position Workspace::supportedTilingResizeMode(Client *c, KDe
return currentMode; return currentMode;
} }
void Workspace::dumpTiles() const void Tiling::dumpTiles() const
{ {
foreach (TilingLayout * t, tilingLayouts) { foreach (TilingLayout * t, tilingLayouts) {
if (!t) { if (!t) {
@ -455,5 +461,10 @@ void Workspace::dumpTiles() const
} }
} }
} }
} // namespace
QVector< TilingLayout* >& Tiling::getTilingLayouts()
{
return tilingLayouts;
}
}

108
tiling/tiling.h Normal file
View File

@ -0,0 +1,108 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Nikhil Marathe <nsm.nikhil@gmail.com>
Copyright (C) 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_TILING_H
#define KWIN_TILING_H
#include <kdecoration.h>
#include "client.h"
#include <QtCore/QVector>
namespace KWin {
class Tile;
class TilingLayout;
class Tiling : public QObject {
Q_OBJECT
public:
Tiling(Workspace *w);
~Tiling();
bool tilingEnabled() const;
void setTilingEnabled(bool tiling);
bool tileable(Client *c);
void createTile(Client *c);
void removeTile(Client *c);
// updates geometry of tiles on all desktops,
// this rearranges the tiles.
void updateAllTiles();
QVector< TilingLayout* >& getTilingLayouts();
// 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, KDecorationDefines::WindowOperation op);
KDecorationDefines::Position supportedTilingResizeMode(Client *c, KDecorationDefines::Position currentMode);
public Q_SLOTS:
// 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;
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 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<TilingLayout *> tilingLayouts;
};
}
#endif // KWIN_TILING_H

View File

@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "client.h" #include "client.h"
#include "tile.h" #include "tile.h"
#include "workspace.h" #include "workspace.h"
#include "tiling/tiling.h"
namespace KWin namespace KWin
{ {
@ -194,7 +195,7 @@ void TilingLayout::reconfigureTiling()
foreach (Client * c, workspace()->stackingOrder()) { foreach (Client * c, workspace()->stackingOrder()) {
if (c->rules()->checkTilingOption(0) == 1) if (c->rules()->checkTilingOption(0) == 1)
workspace()->createTile(c); workspace()->tiling()->createTile(c);
} }
} }

View File

@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "effects.h" #include "effects.h"
#include "tile.h" #include "tile.h"
#include "tilinglayout.h" #include "tilinglayout.h"
#include "tiling/tiling.h"
#include "kactivityinfo.h" #include "kactivityinfo.h"
@ -198,7 +199,7 @@ QMenu* Workspace::clientPopup()
// then hide it // then hide it
mTilingStateOpAction->setVisible(false); mTilingStateOpAction->setVisible(false);
// actions for window tiling // actions for window tiling
if (tilingEnabled()) { if (m_tiling->tilingEnabled()) {
kaction = qobject_cast<KAction*>(keys->action("Toggle Floating")); kaction = qobject_cast<KAction*>(keys->action("Toggle Floating"));
mTilingStateOpAction->setCheckable(true); mTilingStateOpAction->setCheckable(true);
mTilingStateOpAction->setData(Options::ToggleClientTiledStateOp); mTilingStateOpAction->setData(Options::ToggleClientTiledStateOp);
@ -289,15 +290,15 @@ void Workspace::clientPopupAboutToShow()
mMinimizeOpAction->setEnabled(active_popup_client->isMinimizable()); mMinimizeOpAction->setEnabled(active_popup_client->isMinimizable());
mCloseOpAction->setEnabled(active_popup_client->isCloseable()); mCloseOpAction->setEnabled(active_popup_client->isCloseable());
if (tilingEnabled()) { if (m_tiling->tilingEnabled()) {
int desktop = active_popup_client->desktop(); int desktop = active_popup_client->desktop();
if (tilingLayouts.value(desktop)) { if (m_tiling->getTilingLayouts().value(desktop)) {
Tile *t = tilingLayouts[desktop]->findTile(active_popup_client); Tile *t = m_tiling->getTilingLayouts()[desktop]->findTile(active_popup_client);
if (t) if (t)
mTilingStateOpAction->setChecked(t->floating()); mTilingStateOpAction->setChecked(t->floating());
} }
} }
mTilingStateOpAction->setVisible(tilingEnabled()); mTilingStateOpAction->setVisible(m_tiling->tilingEnabled());
delete switch_to_tab_popup; delete switch_to_tab_popup;
switch_to_tab_popup = 0; switch_to_tab_popup = 0;
@ -661,12 +662,12 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op)
return; return;
// Allows us to float a window when it is maximized, if it is tiled. // Allows us to float a window when it is maximized, if it is tiled.
if (tilingEnabled() if (m_tiling->tilingEnabled()
&& (op == Options::MaximizeOp && (op == Options::MaximizeOp
|| op == Options::HMaximizeOp || op == Options::HMaximizeOp
|| op == Options::VMaximizeOp || op == Options::VMaximizeOp
|| op == Options::RestoreOp)) { || op == Options::RestoreOp)) {
notifyTilingWindowMaximized(c, op); m_tiling->notifyTilingWindowMaximized(c, op);
} }
if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp) if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp)
@ -780,8 +781,8 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op)
c->clientGroup()->closeAll(); c->clientGroup()->closeAll();
case Options::ToggleClientTiledStateOp: { case Options::ToggleClientTiledStateOp: {
int desktop = c->desktop(); int desktop = c->desktop();
if (tilingLayouts.value(desktop)) { if (m_tiling->getTilingLayouts().value(desktop)) {
tilingLayouts[desktop]->toggleFloatTile(c); m_tiling->getTilingLayouts()[desktop]->toggleFloatTile(c);
} }
} }
} }

View File

@ -63,6 +63,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "effects.h" #include "effects.h"
#include "overlaywindow.h" #include "overlaywindow.h"
#include "tilinglayout.h" #include "tilinglayout.h"
#include "tiling/tiling.h"
#ifdef KWIN_BUILD_SCRIPTING #ifdef KWIN_BUILD_SCRIPTING
#include "scripting/scripting.h" #include "scripting/scripting.h"
@ -107,7 +108,6 @@ Workspace::Workspace(bool restore)
, desktopGridSize_(1, 2) // Default to two rows , desktopGridSize_(1, 2) // Default to two rows
, desktopGrid_(new int[2]) , desktopGrid_(new int[2])
, currentDesktop_(0) , currentDesktop_(0)
, tilingEnabled_(false)
// Unsorted // Unsorted
, active_popup(NULL) , active_popup(NULL)
, active_popup_client(NULL) , active_popup_client(NULL)
@ -235,11 +235,14 @@ Workspace::Workspace(bool restore)
); );
client_keys = new KActionCollection(this); client_keys = new KActionCollection(this);
initShortcuts();
#ifdef KWIN_BUILD_DESKTOPCHANGEOSD #ifdef KWIN_BUILD_DESKTOPCHANGEOSD
desktop_change_osd = new DesktopChangeOSD(this); desktop_change_osd = new DesktopChangeOSD(this);
#endif #endif
m_outline = new Outline(); m_outline = new Outline();
m_tiling = new Tiling(this);
initShortcuts();
init(); init();
@ -488,7 +491,7 @@ void Workspace::init()
activateClient(new_active_client); activateClient(new_active_client);
// Enable/disable tiling // Enable/disable tiling
setTilingEnabled(options->tilingOn); m_tiling->setTilingEnabled(options->tilingOn);
// SELI TODO: This won't work with unreasonable focus policies, // SELI TODO: This won't work with unreasonable focus policies,
// and maybe in rare cases also if the selected client doesn't // and maybe in rare cases also if the selected client doesn't
@ -525,6 +528,7 @@ Workspace::~Workspace()
delete desktop_change_osd; delete desktop_change_osd;
#endif #endif
delete m_outline; delete m_outline;
delete m_tiling;
discardPopup(); discardPopup();
XDeleteProperty(display(), rootWindow(), atoms->kwin_running); XDeleteProperty(display(), rootWindow(), atoms->kwin_running);
@ -562,9 +566,9 @@ Client* Workspace::createClient(Window w, bool is_mapped)
} }
addClient(c, Allowed); addClient(c, Allowed);
tilingLayouts.resize(numberOfDesktops() + 1); m_tiling->getTilingLayouts().resize(numberOfDesktops() + 1);
m_tiling->createTile(c);
createTile(c);
return c; return c;
} }
@ -668,8 +672,8 @@ void Workspace::removeClient(Client* c, allowed_t)
#endif #endif
Q_ASSERT(clients.contains(c) || desktops.contains(c)); Q_ASSERT(clients.contains(c) || desktops.contains(c));
if (tilingEnabled() && tilingLayouts.value(c->desktop())) { if (m_tiling->tilingEnabled() && m_tiling->getTilingLayouts().value(c->desktop())) {
removeTile(c); m_tiling->removeTile(c);
} }
// TODO: if marked client is removed, notify the marked list // TODO: if marked client is removed, notify the marked list
clients.removeAll(c); clients.removeAll(c);
@ -1027,13 +1031,13 @@ void Workspace::slotReconfigure()
} }
} }
setTilingEnabled(options->tilingOn); m_tiling->setTilingEnabled(options->tilingOn);
foreach (TilingLayout * layout, tilingLayouts) { foreach (TilingLayout * layout, m_tiling->getTilingLayouts()) {
if (layout) if (layout)
layout->reconfigureTiling(); layout->reconfigureTiling();
} }
// just so that we reset windows in the right manner, 'activate' the current active window // just so that we reset windows in the right manner, 'activate' the current active window
notifyTilingWindowActivated(activeClient()); m_tiling->notifyTilingWindowActivated(activeClient());
if (hasDecorationPlugin()) { if (hasDecorationPlugin()) {
rootInfo->setSupported(NET::WM2FrameOverlap, mgr->factory()->supports(AbilityExtendIntoClientArea)); rootInfo->setSupported(NET::WM2FrameOverlap, mgr->factory()->supports(AbilityExtendIntoClientArea));
} else { } else {
@ -1296,8 +1300,8 @@ bool Workspace::setCurrentDesktop(int new_desktop)
if (movingClient && !movingClient->isOnDesktop(new_desktop)) { if (movingClient && !movingClient->isOnDesktop(new_desktop)) {
int old_desktop = movingClient->desktop(); int old_desktop = movingClient->desktop();
movingClient->setDesktop(new_desktop); movingClient->setDesktop(new_desktop);
if (tilingEnabled()) { if (m_tiling->tilingEnabled()) {
notifyTilingWindowDesktopChanged(movingClient, old_desktop); m_tiling->notifyTilingWindowDesktopChanged(movingClient, old_desktop);
} }
} }
@ -1577,7 +1581,7 @@ void Workspace::setNumberOfDesktops(int n)
for (int i = 0; i < int(desktop_focus_chain.size()); i++) for (int i = 0; i < int(desktop_focus_chain.size()); i++)
desktop_focus_chain[i] = i + 1; desktop_focus_chain[i] = i + 1;
tilingLayouts.resize(numberOfDesktops() + 1); m_tiling->getTilingLayouts().resize(numberOfDesktops() + 1);
saveDesktopSettings(); saveDesktopSettings();
emit numberDesktopsChanged(old_number_of_desktops); emit numberDesktopsChanged(old_number_of_desktops);
@ -1611,7 +1615,7 @@ void Workspace::sendClientToDesktop(Client* c, int desk, bool dont_activate)
} else } else
raiseClient(c); raiseClient(c);
notifyTilingWindowDesktopChanged(c, old_desktop); m_tiling->notifyTilingWindowDesktopChanged(c, old_desktop);
ClientList transients_stacking_order = ensureStackingOrder(c->transients()); ClientList transients_stacking_order = ensureStackingOrder(c->transients());
for (ClientList::ConstIterator it = transients_stacking_order.constBegin(); for (ClientList::ConstIterator it = transients_stacking_order.constBegin();
@ -2151,6 +2155,47 @@ TabBox::TabBox* Workspace::tabBox() const
} }
#endif #endif
Tiling* Workspace::tiling()
{
return m_tiling;
}
/*
* Called from D-BUS
*/
void Workspace::toggleTiling()
{
if (m_tiling) {
m_tiling->slotToggleTiling();
}
}
/*
* Called from D-BUS
*/
void Workspace::nextTileLayout()
{
if (m_tiling) {
m_tiling->slotNextTileLayout();
}
}
/*
* Called from D-BUS
*/
void Workspace::previousTileLayout()
{
if (m_tiling) {
m_tiling->slotPreviousTileLayout();
}
}
void Workspace::dumpTiles() const {
if (m_tiling) {
m_tiling->dumpTiles();
}
}
} // namespace } // namespace
#include "workspace.moc" #include "workspace.moc"

View File

@ -74,6 +74,7 @@ class TabBox;
class Client; class Client;
class Tile; class Tile;
class Tiling;
class TilingLayout; class TilingLayout;
class ClientGroup; class ClientGroup;
#ifdef KWIN_BUILD_DESKTOPCHANGEOSD #ifdef KWIN_BUILD_DESKTOPCHANGEOSD
@ -197,31 +198,7 @@ public:
return unmanaged; return unmanaged;
} }
//------------------------------------------------- Tiling* tiling();
// 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);
Outline* outline(); Outline* outline();
#ifdef KWIN_BUILD_SCREENEDGES #ifdef KWIN_BUILD_SCREENEDGES
@ -329,14 +306,10 @@ private:
KActivityController activityController_; KActivityController activityController_;
bool tilingEnabled_; Tiling* m_tiling;
// 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<TilingLayout *> tilingLayouts;
Outline* m_outline; Outline* m_outline;
#ifdef KWIN_BUILD_SCREENEDGES #ifdef KWIN_BUILD_SCREENEDGES
ScreenEdge m_screenEdge; ScreenEdge m_screenEdge;
#endif #endif
@ -640,25 +613,6 @@ public slots:
void suspendCompositing(); void suspendCompositing();
void suspendCompositing(bool suspend); 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 // NOTE: debug method
void dumpTiles() const; void dumpTiles() const;
@ -805,16 +759,6 @@ private:
static NET::WindowType txtToWindowType(const char* txt); static NET::WindowType txtToWindowType(const char* txt);
static bool sessionInfoWindowTypeMatch(Client* c, SessionInfo* info); 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* active_client;
Client* last_active_client; Client* last_active_client;
Client* most_recently_raised; // Used ONLY by raiseOrLowerClient() Client* most_recently_raised; // Used ONLY by raiseOrLowerClient()
@ -1263,30 +1207,6 @@ inline void Workspace::removeClientGroup(ClientGroup* group)
clientGroups.removeAll(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 } // namespace
#endif #endif