// WorkspaceCmd.cc for Fluxbox - an X11 Window manager // Copyright (c) 2003 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org) // and Simon Bowden (rathnor at users.sourceforge.net) // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // $Id$ #include "WorkspaceCmd.hh" #include "Workspace.hh" #include "Window.hh" #include "Screen.hh" #include "fluxbox.hh" #include "WinClient.hh" #include "FbTk/KeyUtil.hh" #ifdef HAVE_CMATH #include <cmath> #else #include <math.h> #endif #include <algorithm> #include <functional> #include <iostream> void NextWindowCmd::execute() { BScreen *screen = Fluxbox::instance()->keyScreen(); if (screen != 0) { Fluxbox *fb = Fluxbox::instance(); // special case for commands from key events if (fb->lastEvent().type == KeyPress) { unsigned int mods = FbTk::KeyUtil::instance().cleanMods(fb->lastEvent().xkey.state); if (mods == 0) // can't stacked cycle unless there is a mod to grab screen->nextFocus(m_option | BScreen::CYCLELINEAR); else { // if stacked cycling, then set a watch for // the release of exactly these modifiers if (!fb->watchingScreen() && !(m_option & BScreen::CYCLELINEAR)) Fluxbox::instance()->watchKeyRelease(*screen, mods); screen->nextFocus(m_option); } } else screen->nextFocus(m_option); } } void PrevWindowCmd::execute() { BScreen *screen = Fluxbox::instance()->keyScreen(); if (screen != 0) { Fluxbox *fb = Fluxbox::instance(); // special case for commands from key events if (fb->lastEvent().type == KeyPress) { unsigned int mods = FbTk::KeyUtil::instance().cleanMods(fb->lastEvent().xkey.state); if (mods == 0) // can't stacked cycle unless there is a mod to grab screen->prevFocus(m_option | BScreen::CYCLELINEAR); else { // if stacked cycling, then set a watch for // the release of exactly these modifiers if (!fb->watchingScreen() && !(m_option & BScreen::CYCLELINEAR)) Fluxbox::instance()->watchKeyRelease(*screen, mods); screen->prevFocus(m_option); } } else screen->nextFocus(m_option); } } void DirFocusCmd::execute() { BScreen *screen = Fluxbox::instance()->keyScreen(); if (screen == 0) return; WinClient *client = Fluxbox::instance()->getFocusedWindow(); if (client == 0 || client->fbwindow() == 0) return; screen->dirFocus(*client->fbwindow(), m_dir); } void NextWorkspaceCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen != 0) screen->nextWorkspace(); } void PrevWorkspaceCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen != 0) screen->prevWorkspace(); } void LeftWorkspaceCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen != 0) screen->leftWorkspace(m_param); } void RightWorkspaceCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen != 0) screen->rightWorkspace(m_param); } JumpToWorkspaceCmd::JumpToWorkspaceCmd(int workspace_num):m_workspace_num(workspace_num) { } void JumpToWorkspaceCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen != 0 && m_workspace_num >= 0 && m_workspace_num < screen->getNumberOfWorkspaces()) screen->changeWorkspaceID(m_workspace_num); } void ArrangeWindowsCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen == 0) return; Workspace *space = screen->currentWorkspace(); const unsigned int win_count = space->windowList().size(); if (win_count == 0) return; const int head = screen->getCurrHead(); const unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head); const unsigned int max_heigth = screen->maxBottom(head) - screen->maxTop(head); // try to get the same number of rows as columns. unsigned int rows = int(sqrt((float)win_count)); // truncate to lower unsigned int cols = int(0.99 + float(win_count) / float(rows)); if (max_width<max_heigth) { // rotate unsigned int tmp; tmp = rows; rows = cols; cols = tmp; } const unsigned int cal_width = max_width/cols; // calculated width ratio (width of every window) const unsigned int cal_heigth = max_heigth/rows; // heigth ratio (heigth of every window) // Resizes and sets windows positions in columns and rows. unsigned int x_offs = 0; // window position offset in x unsigned int y_offs = 0; // window position offset in y unsigned int window = 0; // current window Workspace::Windows &windowlist = space->windowList(); for (unsigned int i = 0; i < rows; ++i) { x_offs = 0; for (unsigned int j = 0; j < cols && window < win_count; ++j, ++window) { if (window==(win_count-1)) { // the last window gets everything that is left. windowlist[window]->moveResize(x_offs, y_offs, max_width-x_offs, cal_heigth); } else { windowlist[window]->moveResize(x_offs, y_offs, cal_width, cal_heigth); } // next x offset x_offs += cal_width; } // next y offset y_offs += cal_heigth; } } void ShowDesktopCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen == 0) return; Workspace *space = screen->currentWorkspace(); std::for_each(space->windowList().begin(), space->windowList().end(), std::mem_fun(&FluxboxWindow::iconify)); }