diff --git a/activation.cpp b/activation.cpp index 1f67f96a42..c07a2b63cd 100644 --- a/activation.cpp +++ b/activation.cpp @@ -42,6 +42,7 @@ along with this program. If not, see . #include "group.h" #include "rules.h" #include +#include "tiling/tiling.h" namespace KWin { @@ -263,8 +264,8 @@ void Workspace::setActiveClient(Client* c, allowed_t) active_client->sl_activated(); } - if (tilingEnabled()) - notifyTilingWindowActivated(active_client); + if (m_tiling->tilingEnabled()) + m_tiling->notifyTilingWindowActivated(active_client); --set_active_client_recursion; } diff --git a/client.cpp b/client.cpp index c4fdd95d87..fe5016c3db 100644 --- a/client.cpp +++ b/client.cpp @@ -47,6 +47,7 @@ along with this program. If not, see . #include "notifications.h" #include "rules.h" #include "shadow.h" +#include "tiling/tiling.h" #include "deleted.h" #include "paintredirector.h" #ifdef KWIN_BUILD_TABBOX @@ -951,7 +952,7 @@ void Client::minimize(bool avoid_animation) emit clientMinimized(this, !avoid_animation); // when tiling, request a rearrangement - workspace()->notifyTilingWindowMinimizeToggled(this); + workspace()->tiling()->notifyTilingWindowMinimizeToggled(this); // Update states of all other windows in this group if (clientGroup()) @@ -978,11 +979,11 @@ void Client::unminimize(bool avoid_animation) updateAllowedActions(); workspace()->updateMinimizedOfTransients(this); updateWindowRules(); - workspace()->updateAllTiles(); + workspace()->tiling()->updateAllTiles(); emit clientUnminimized(this, !avoid_animation); // when tiling, request a rearrangement - workspace()->notifyTilingWindowMinimizeToggled(this); + workspace()->tiling()->notifyTilingWindowMinimizeToggled(this); // Update states of all other windows in this group if (clientGroup()) diff --git a/geometry.cpp b/geometry.cpp index a357162b15..43e66eadc3 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -50,6 +50,7 @@ along with this program. If not, see . #include #include #include "outline.h" +#include "tiling/tiling.h" namespace KWin { @@ -2032,7 +2033,7 @@ void Client::move(int x, int y, ForceGeometry_t force) workspace()->checkActiveScreen(this); workspace()->updateStackingOrder(); workspace()->checkUnredirect(); - workspace()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom); + workspace()->tiling()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom); // client itself is not damaged const QRect deco_rect = decorationRect().translated(geom.x(), geom.y()); addWorkspaceRepaint(deco_rect_before_block); @@ -2590,11 +2591,11 @@ void Client::finishMoveResize(bool cancel) leaveMoveResize(); - if (workspace()->tilingEnabled()) { + if (workspace()->tiling()->tilingEnabled()) { 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); @@ -2763,8 +2764,8 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root) bool update = false; if (isResize()) { // query layout for supported resize mode - if (workspace()->tilingEnabled()) { - mode = workspace()->supportedTilingResizeMode(this, mode); + if (workspace()->tiling()->tilingEnabled()) { + mode = workspace()->tiling()->supportedTilingResizeMode(this, mode); } // first resize (without checking constrains), then snap, then check bounds, then check constrains QRect orig = initialMoveResizeGeom; @@ -2801,7 +2802,7 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root) case PositionCenter: // exception for tiling // Center means no resizing allowed - if (workspace()->tilingEnabled()) { + if (workspace()->tiling()->tilingEnabled()) { finishMoveResize(false); buttonDown = false; return; @@ -2810,7 +2811,7 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root) abort(); break; } - workspace()->notifyTilingWindowResize(this, moveResizeGeom, initialMoveResizeGeom); + workspace()->tiling()->notifyTilingWindowResize(this, moveResizeGeom, initialMoveResizeGeom); // adjust new size to snap to other windows/borders moveResizeGeom = workspace()->adjustClientSize(this, moveResizeGeom, mode); @@ -2968,7 +2969,7 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root) performMoveResize(); if (isMove()) { - workspace()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom); + workspace()->tiling()->notifyTilingWindowMove(this, moveResizeGeom, initialMoveResizeGeom); #ifdef KWIN_BUILD_SCREENEDGES workspace()->screenEdge()->check(globalPos, xTime()); #endif @@ -2986,7 +2987,7 @@ void Client::performMoveResize() sendSyncRequest(); } #endif - if (!workspace()->tilingEnabled()) + if (!workspace()->tiling()->tilingEnabled()) setGeometry(moveResizeGeom); positionGeometryTip(); emit clientStepUserMovedResized(this, moveResizeGeom); diff --git a/sm.cpp b/sm.cpp index db44ce008d..d2111d1a7c 100644 --- a/sm.cpp +++ b/sm.cpp @@ -34,6 +34,7 @@ along with this program. If not, see . #include #include #include +#include "tiling/tiling.h" namespace KWin { @@ -84,10 +85,10 @@ void Workspace::storeSession(KConfig* config, SMSavePhase phase) int active_client = -1; if (phase == SMSavePhase2 || phase == SMSavePhase2Full) { - cg.writeEntry("tiling", tilingEnabled()); - if (tilingEnabled()) { + cg.writeEntry("tiling", m_tiling->tilingEnabled()); + if (m_tiling->tilingEnabled()) { kDebug(1212) << "Tiling was ON"; - setTilingEnabled(false); + m_tiling->setTilingEnabled(false); } } @@ -273,7 +274,7 @@ void Workspace::loadSessionInfo() session.clear(); KConfigGroup cg(kapp->sessionConfig(), "Session"); - setTilingEnabled(cg.readEntry("tiling", false)); + m_tiling->setTilingEnabled(cg.readEntry("tiling", false)); addSessionInfo(cg); } diff --git a/tile.cpp b/tile.cpp index a188129581..ee1f848a09 100644 --- a/tile.cpp +++ b/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/tiling/tiling.cpp b/tiling/tiling.cpp index 85b22274db..9ab3a5fa1e 100644 --- a/tiling/tiling.cpp +++ b/tiling/tiling.cpp @@ -3,6 +3,7 @@ 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 @@ -18,30 +19,36 @@ 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 -#include "client.h" -#include "workspace.h" -#include "tile.h" -#include "tilinglayout.h" -#include "tilinglayoutfactory.h" - -#include #include +#include #include #include +#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_; } -void Workspace::setTilingEnabled(bool tiling) +void Tiling::setTilingEnabled(bool tiling) { if (tilingEnabled() == tiling) return; @@ -56,8 +63,8 @@ void Workspace::setTilingEnabled(bool tiling) options->tilingRaisePolicy = config.readEntry("TilingRaisePolicy", 0); if (tilingEnabled_) { - tilingLayouts.resize(numberOfDesktops() + 1); - foreach (Client * c, stackingOrder()) { + tilingLayouts.resize(Workspace::self()->numberOfDesktops() + 1); + foreach (Client * c, Workspace::self()->stackingOrder()) { createTile(c); } } else { @@ -66,7 +73,7 @@ void Workspace::setTilingEnabled(bool tiling) } } -void Workspace::slotToggleTiling() +void Tiling::slotToggleTiling() { if (tilingEnabled()) { setTilingEnabled(false); @@ -79,7 +86,7 @@ void Workspace::slotToggleTiling() } } -void Workspace::createTile(Client *c) +void Tiling::createTile(Client* c) { if (c == NULL) return; @@ -90,28 +97,27 @@ void Workspace::createTile(Client *c) if (!tilingEnabled() || !tileable(c)) return; - Tile *t = new Tile(c, clientArea(PlacementArea, c)); + Tile *t = new Tile(c, Workspace::self()->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()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, m_workspace); } tilingLayouts[c->desktop()]->addTile(t); tilingLayouts[c->desktop()]->commit(); } -void Workspace::removeTile(Client *c) +void Tiling::removeTile(Client *c) { if (tilingLayouts[ c->desktop()]) tilingLayouts[ c->desktop()]->removeTile(c); } -bool Workspace::tileable(Client *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(); @@ -134,21 +140,21 @@ bool Workspace::tileable(Client *c) return true; } -void Workspace::belowCursor() +void Tiling::belowCursor() { // TODO } -Tile* Workspace::getNiceTile() const +Tile* Tiling::getNiceTile() const { 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 } -void Workspace::updateAllTiles() +void Tiling::updateAllTiles() { foreach (TilingLayout * t, tilingLayouts) { if (!t) continue; @@ -159,14 +165,14 @@ void Workspace::updateAllTiles() /* * 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) return; 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) { return; @@ -175,7 +181,7 @@ void Workspace::notifyTilingWindowMove(Client *c, const QRect &moveResizeGeom, c 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) notifyTilingWindowResize(c, orig, moveResizeGeom); @@ -183,7 +189,7 @@ void Workspace::notifyTilingWindowResizeDone(Client *c, const QRect &moveResizeG 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) notifyTilingWindowMove(c, orig, moveResizeGeom); @@ -191,9 +197,9 @@ void Workspace::notifyTilingWindowMoveDone(Client *c, const QRect &moveResizeGeo 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; 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? if (!tilingLayouts.value(c->desktop())) { - tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, this); + tilingLayouts[c->desktop()] = TilingLayoutFactory::createLayout(TilingLayoutFactory::DefaultLayout, m_workspace); } if (t) @@ -215,7 +221,7 @@ void Workspace::notifyTilingWindowDesktopChanged(Client *c, int old_desktop) /* * Implements the 3 raising modes in Window Behaviour -> Advanced */ -void Workspace::notifyTilingWindowActivated(Client *c) +void Tiling::notifyTilingWindowActivated(Client *c) { if (c == NULL) return; @@ -226,7 +232,7 @@ void Workspace::notifyTilingWindowActivated(Client *c) if (tilingLayouts.value(c->desktop())) { QList tiles = tilingLayouts[ c->desktop()]->tiles(); - StackingUpdatesBlocker blocker(this); + StackingUpdatesBlocker blocker(m_workspace); Tile *tile_to_raise = tilingLayouts[ c->desktop()]->findTile(c); @@ -243,24 +249,24 @@ void Workspace::notifyTilingWindowActivated(Client *c) foreach (Tile * t, tiles) { 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 // 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()); + m_workspace->raiseClient(tile_to_raise->client()); } } -void Workspace::notifyTilingWindowMinimizeToggled(Client *c) +void Tiling::notifyTilingWindowMinimizeToggled(Client *c) { if (tilingLayouts.value(c->desktop())) { 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())) { 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(); QPoint origin = reference.center(); @@ -346,17 +352,17 @@ Tile* Workspace::findAdjacentTile(Tile *ref, int d) return closest; } -void Workspace::focusTile(int d) +void Tiling::focusTile(int d) { Tile *t = getNiceTile(); if (t) { Tile *adj = findAdjacentTile(t, d); if (adj) - activateClient(adj->client()); + m_workspace->activateClient(adj->client()); } } -void Workspace::moveTile(int d) +void Tiling::moveTile(int d) { Tile *t = getNiceTile(); if (t) { @@ -366,75 +372,75 @@ void Workspace::moveTile(int d) } } -void Workspace::slotFocusTileLeft() +void Tiling::slotFocusTileLeft() { focusTile(Tile::Left); } -void Workspace::slotFocusTileRight() +void Tiling::slotFocusTileRight() { focusTile(Tile::Right); } -void Workspace::slotFocusTileTop() +void Tiling::slotFocusTileTop() { focusTile(Tile::Top); } -void Workspace::slotFocusTileBottom() +void Tiling::slotFocusTileBottom() { focusTile(Tile::Bottom); } -void Workspace::slotMoveTileLeft() +void Tiling::slotMoveTileLeft() { moveTile(Tile::Left); } -void Workspace::slotMoveTileRight() +void Tiling::slotMoveTileRight() { moveTile(Tile::Right); } -void Workspace::slotMoveTileTop() +void Tiling::slotMoveTileTop() { moveTile(Tile::Top); } -void Workspace::slotMoveTileBottom() +void Tiling::slotMoveTileBottom() { moveTile(Tile::Bottom); } -void Workspace::slotToggleFloating() +void Tiling::slotToggleFloating() { - Client *c = activeClient(); + Client *c = m_workspace->activeClient(); if (tilingLayouts.value(c->desktop())) { 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())) { return tilingLayouts[c->desktop()]->resizeMode(c, currentMode); @@ -442,7 +448,7 @@ KDecorationDefines::Position Workspace::supportedTilingResizeMode(Client *c, KDe return currentMode; } -void Workspace::dumpTiles() const +void Tiling::dumpTiles() const { foreach (TilingLayout * t, tilingLayouts) { if (!t) { @@ -455,5 +461,10 @@ void Workspace::dumpTiles() const } } } -} // namespace +QVector< TilingLayout* >& Tiling::getTilingLayouts() +{ + return tilingLayouts; +} + +} diff --git a/tiling/tiling.h b/tiling/tiling.h new file mode 100644 index 0000000000..fcd8f4382a --- /dev/null +++ b/tiling/tiling.h @@ -0,0 +1,108 @@ +/******************************************************************** + 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 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 tilingLayouts; +}; +} + +#endif // KWIN_TILING_H \ No newline at end of file diff --git a/tilinglayout.cpp b/tilinglayout.cpp index 6e1152b15c..c7ab849fa0 100644 --- a/tilinglayout.cpp +++ b/tilinglayout.cpp @@ -25,6 +25,7 @@ along with this program. If not, see . #include "client.h" #include "tile.h" #include "workspace.h" +#include "tiling/tiling.h" namespace KWin { @@ -194,7 +195,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/useractions.cpp b/useractions.cpp index 387e4992b7..66b5efd876 100644 --- a/useractions.cpp +++ b/useractions.cpp @@ -32,6 +32,7 @@ along with this program. If not, see . #include "effects.h" #include "tile.h" #include "tilinglayout.h" +#include "tiling/tiling.h" #include "kactivityinfo.h" @@ -198,7 +199,7 @@ QMenu* Workspace::clientPopup() // then hide it mTilingStateOpAction->setVisible(false); // actions for window tiling - if (tilingEnabled()) { + if (m_tiling->tilingEnabled()) { kaction = qobject_cast(keys->action("Toggle Floating")); mTilingStateOpAction->setCheckable(true); mTilingStateOpAction->setData(Options::ToggleClientTiledStateOp); @@ -289,15 +290,15 @@ void Workspace::clientPopupAboutToShow() mMinimizeOpAction->setEnabled(active_popup_client->isMinimizable()); mCloseOpAction->setEnabled(active_popup_client->isCloseable()); - if (tilingEnabled()) { + if (m_tiling->tilingEnabled()) { int desktop = active_popup_client->desktop(); - if (tilingLayouts.value(desktop)) { - Tile *t = tilingLayouts[desktop]->findTile(active_popup_client); + if (m_tiling->getTilingLayouts().value(desktop)) { + Tile *t = m_tiling->getTilingLayouts()[desktop]->findTile(active_popup_client); if (t) mTilingStateOpAction->setChecked(t->floating()); } } - mTilingStateOpAction->setVisible(tilingEnabled()); + mTilingStateOpAction->setVisible(m_tiling->tilingEnabled()); delete switch_to_tab_popup; switch_to_tab_popup = 0; @@ -661,12 +662,12 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op) return; // 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::HMaximizeOp || op == Options::VMaximizeOp || op == Options::RestoreOp)) { - notifyTilingWindowMaximized(c, op); + m_tiling->notifyTilingWindowMaximized(c, op); } if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp) @@ -780,8 +781,8 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op) c->clientGroup()->closeAll(); case Options::ToggleClientTiledStateOp: { int desktop = c->desktop(); - if (tilingLayouts.value(desktop)) { - tilingLayouts[desktop]->toggleFloatTile(c); + if (m_tiling->getTilingLayouts().value(desktop)) { + m_tiling->getTilingLayouts()[desktop]->toggleFloatTile(c); } } } diff --git a/workspace.cpp b/workspace.cpp index b9556681b2..f742288224 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -63,6 +63,7 @@ along with this program. If not, see . #include "effects.h" #include "overlaywindow.h" #include "tilinglayout.h" +#include "tiling/tiling.h" #ifdef KWIN_BUILD_SCRIPTING #include "scripting/scripting.h" @@ -107,7 +108,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 +235,14 @@ 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(); + m_tiling = new Tiling(this); + + initShortcuts(); init(); @@ -488,7 +491,7 @@ void Workspace::init() activateClient(new_active_client); // Enable/disable tiling - setTilingEnabled(options->tilingOn); + m_tiling->setTilingEnabled(options->tilingOn); // SELI TODO: This won't work with unreasonable focus policies, // and maybe in rare cases also if the selected client doesn't @@ -525,6 +528,7 @@ Workspace::~Workspace() delete desktop_change_osd; #endif delete m_outline; + delete m_tiling; discardPopup(); XDeleteProperty(display(), rootWindow(), atoms->kwin_running); @@ -562,9 +566,9 @@ Client* Workspace::createClient(Window w, bool is_mapped) } addClient(c, Allowed); - tilingLayouts.resize(numberOfDesktops() + 1); + m_tiling->getTilingLayouts().resize(numberOfDesktops() + 1); + m_tiling->createTile(c); - createTile(c); return c; } @@ -668,8 +672,8 @@ void Workspace::removeClient(Client* c, allowed_t) #endif Q_ASSERT(clients.contains(c) || desktops.contains(c)); - if (tilingEnabled() && tilingLayouts.value(c->desktop())) { - removeTile(c); + if (m_tiling->tilingEnabled() && m_tiling->getTilingLayouts().value(c->desktop())) { + m_tiling->removeTile(c); } // TODO: if marked client is removed, notify the marked list clients.removeAll(c); @@ -1027,13 +1031,13 @@ void Workspace::slotReconfigure() } } - setTilingEnabled(options->tilingOn); - foreach (TilingLayout * layout, tilingLayouts) { + m_tiling->setTilingEnabled(options->tilingOn); + foreach (TilingLayout * layout, m_tiling->getTilingLayouts()) { if (layout) layout->reconfigureTiling(); } // just so that we reset windows in the right manner, 'activate' the current active window - notifyTilingWindowActivated(activeClient()); + m_tiling->notifyTilingWindowActivated(activeClient()); if (hasDecorationPlugin()) { rootInfo->setSupported(NET::WM2FrameOverlap, mgr->factory()->supports(AbilityExtendIntoClientArea)); } else { @@ -1296,8 +1300,8 @@ 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); + if (m_tiling->tilingEnabled()) { + 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++) desktop_focus_chain[i] = i + 1; - tilingLayouts.resize(numberOfDesktops() + 1); + m_tiling->getTilingLayouts().resize(numberOfDesktops() + 1); saveDesktopSettings(); emit numberDesktopsChanged(old_number_of_desktops); @@ -1611,7 +1615,7 @@ void Workspace::sendClientToDesktop(Client* c, int desk, bool dont_activate) } else raiseClient(c); - notifyTilingWindowDesktopChanged(c, old_desktop); + m_tiling->notifyTilingWindowDesktopChanged(c, old_desktop); ClientList transients_stacking_order = ensureStackingOrder(c->transients()); for (ClientList::ConstIterator it = transients_stacking_order.constBegin(); @@ -2151,6 +2155,47 @@ TabBox::TabBox* Workspace::tabBox() const } #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 #include "workspace.moc" diff --git a/workspace.h b/workspace.h index 79c1e2d691..871f74cc61 100644 --- a/workspace.h +++ b/workspace.h @@ -74,6 +74,7 @@ class TabBox; class Client; class Tile; +class Tiling; class TilingLayout; class ClientGroup; #ifdef KWIN_BUILD_DESKTOPCHANGEOSD @@ -197,31 +198,7 @@ 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); + Tiling* tiling(); Outline* outline(); #ifdef KWIN_BUILD_SCREENEDGES @@ -329,14 +306,10 @@ 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; + Tiling* m_tiling; Outline* m_outline; + #ifdef KWIN_BUILD_SCREENEDGES ScreenEdge m_screenEdge; #endif @@ -640,25 +613,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 +759,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 +1207,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