wmi

git clone git://oldgit.suckless.org/wmi/
Log | Files | Refs | LICENSE

actions.cpp (37015B)


      1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us>
      2 // See LICENSE for license details.
      3 
      4 extern "C" {
      5 #include <assert.h>
      6 #include <X11/Xlib.h>
      7 }
      8 #include <sstream>
      9 #include <map>
     10 
     11 #include "actions.h"
     12 
     13 #include "action.h"
     14 #include "binder.h"
     15 #include "client.h"
     16 #include "clientbar.h"
     17 #include "frame.h"
     18 #include "inputbar.h"
     19 #include "launcher.h"
     20 #include "kernel.h"
     21 #include "monitor.h"
     22 #include "logger.h"
     23 #include "expander.h"
     24 #include "prompt.h"
     25 #include "slot.h"
     26 #include "util.h"
     27 #include "validators.h"
     28 #include "workspace.h"
     29 
     30 Actions::Actions() {
     31 }
     32 
     33 Actions::~Actions() {
     34 }
     35 
     36 void Actions::initInternActions(MBindings *actionBindings) {
     37     Action *action = 0;
     38 
     39     (*actionBindings)["restart"] = new Action("restart", &Actions::restart, &Validators::isAlwaysPossible);
     40     (*actionBindings)["quit"] = new Action("quit", &Actions::quit, &Validators::isAlwaysPossible);
     41     (*actionBindings)["save-settings"] = new Action("save-settings", &Actions::saveSettings, &Validators::isAlwaysPossible);
     42 
     43     (*actionBindings)["begin-record"] = new Action("begin-record", &Actions::beginChainRecord, &Validators::validateBeginRecord);
     44 
     45     action = new Action("end-record-chain", &Actions::endChainRecord, &Validators::validateEndRecord);
     46     action->prompts()->push_back(new Prompt("action name : ", 0));
     47     (*actionBindings)["end-record-chain"] = action;
     48 
     49     action = new Action("end-record-script", &Actions::endScriptRecord,
     50                         &Validators::validateEndRecord);
     51     action->prompts()->push_back(new Prompt("script path : ", 0));
     52     (*actionBindings)["end-record-script"] = action;
     53 
     54     (*actionBindings)["cancel-record"] = new Action("cancel-record", &Actions::cancelRecord, &Validators::validateCancelRecord);
     55 
     56     action = new Action("exec-term", &Actions::executeTerm,
     57                         &Validators::isWorkspaceFocused);
     58     action->prompts()->push_back(new Prompt("command : ", &Binder::queryCommandForPattern));
     59     (*actionBindings)["exec-term"] = action;
     60 
     61     (*actionBindings)["rehash"] = new Action("rehash", &Actions::rehash, &Validators::isAlwaysPossible);
     62 
     63     action = new Action("exec", &Actions::execute,
     64                         &Validators::isWorkspaceFocused);
     65     action->prompts()->push_back(new Prompt("command : ", &Binder::queryCommandForPattern));
     66     (*actionBindings)["exec"] = action;
     67 
     68     action = new Action("destroy-action", &Actions::destroyAction,
     69                         &Validators::validateDestroyAction);
     70     action->prompts()->push_back(new Prompt("action to destroy : ",
     71                                     &Binder::queryExternChainActionsForPattern));
     72     (*actionBindings)["destroy-action"] = action;
     73 
     74 #ifdef SLOT_SUPPORT
     75     (*actionBindings)["slot-client"] = new Action("slot-client", &Actions::slotClient, &Validators::isClientFocused);
     76     (*actionBindings)["unslot-client"] = new Action("unslot-client", &Actions::unslotClient, &Validators::existsSlotClient);
     77     (*actionBindings)["toggle-slot"] = new Action("toggle-slot", &Actions::toggleSlot, &Validators::isAlwaysPossible);
     78     (*actionBindings)["cycle-slot-tab-next"] = new Action("cycle-slot-tab-next", &Actions::cycleSlotTabNext, &Validators::existSlotTabs);
     79     (*actionBindings)["cycle-slot-tab-prev"] = new Action("cycle-slot-tab-prev", &Actions::cycleSlotTabPrev, &Validators::existSlotTabs);
     80     (*actionBindings)["kill-slot-client"] = new Action("kill-slot-client", &Actions::killSlotClient, &Validators::existsSlotClient);
     81 #endif // SLOT_SUPPORT
     82 
     83     (*actionBindings)["toggle-client-sticky"] = new Action("toggle-client-sticky", &Actions::toggleClientSticky, &Validators::isClientFocused);
     84 
     85     (*actionBindings)["toggle-client-mode"] = new Action("toggle-client-mode", &Actions::toggleClientMode, &Validators::isFrameOrClientFrameFocused);
     86     (*actionBindings)["grow-left"] = new Action("grow-left", &Actions::growLeft, &Validators::validateResizeLeft);
     87     (*actionBindings)["grow-right"] = new Action("grow-right", &Actions::growRight, &Validators::validateResizeRight);
     88     (*actionBindings)["grow-up"] = new Action("grow-up", &Actions::growUp, &Validators::validateResizeUp);
     89     (*actionBindings)["grow-down"] = new Action("grow-down", &Actions::growDown, &Validators::validateResizeDown);
     90     (*actionBindings)["shrink-left"] = new Action("shrink-left", &Actions::shrinkLeft, &Validators::validateResizeRight);
     91     (*actionBindings)["shrink-right"] = new Action("shrink-right", &Actions::shrinkRight, &Validators::validateResizeLeft);
     92     (*actionBindings)["shrink-up"] = new Action("shrink-up", &Actions::shrinkUp, &Validators::validateResizeDown);
     93     (*actionBindings)["shrink-down"] = new Action("shrink-down", &Actions::shrinkDown, &Validators::validateResizeUp);
     94     (*actionBindings)["move-client-left"] = new Action("move-client-left", &Actions::moveClientLeft, &Validators::isFloatingClientFocused);
     95     (*actionBindings)["move-client-right"] = new Action("move-client-right", &Actions::moveClientRight, &Validators::isFloatingClientFocused);
     96     (*actionBindings)["move-client-up"] = new Action("move-client-up", &Actions::moveClientUp, &Validators::isFloatingClientFocused);
     97     (*actionBindings)["move-client-down"] = new Action("move-client-down", &Actions::moveClientDown, &Validators::isFloatingClientFocused);
     98     (*actionBindings)["show-bars"] = new Action("show-bars", &Actions::showBars, &Validators::isFrameOrClientFrameFocused);
     99     (*actionBindings)["hide-bars"] = new Action("hide-bars", &Actions::hideBars, &Validators::isFrameOrClientFrameFocused);
    100     (*actionBindings)["toggle-bar"] = new Action("toggle-bar", &Actions::toggleBar, &Validators::isFrameOrClientFrameFocused);
    101     (*actionBindings)["show-borders"] = new Action("show-borders", &Actions::showBorders, &Validators::isFrameOrClientFrameFocused);
    102     (*actionBindings)["hide-borders"] = new Action("hide-borders", &Actions::hideBorders, &Validators::isFrameOrClientFrameFocused);
    103     (*actionBindings)["toggle-border"] = new Action("toggle-border", &Actions::toggleBorder, &Validators::isFrameOrClientFrameFocused);
    104     (*actionBindings)["toggle-statusbar"] = new Action("toggle-statusbar", &Actions::toggleStatusBar, &Validators::isAlwaysPossible);
    105     (*actionBindings)["toggle-clientbar"] = new Action("toggle-clientbar", &Actions::toggleClientBar, &Validators::isAlwaysPossible);
    106     (*actionBindings)["kill-client"] = new Action("kill-client", &Actions::killClient, &Validators::isClientFocused);
    107     (*actionBindings)["cycle-client-next"] = new Action("cycle-client-next", &Actions::cycleClientNext, &Validators::existClients);
    108     (*actionBindings)["cycle-workspace-next"] = new Action("cycle-workspace-next", &Actions::cycleWorkspaceNext, &Validators::existWorkspaces);
    109 
    110     (*actionBindings)["toggle-mode"] = new Action("toggle-mode", &Actions::toggleMode, &Validators::validateToggleMode);
    111 
    112     action = new Action("select-monitor", &Actions::selectMonitor, &Validators::existMonitors);
    113     action->prompts()->push_back(new Prompt("monitor : ",
    114                  &Binder::queryMonitorsForPattern));
    115     (*actionBindings)["select-monitor"] = action;
    116 
    117     action = new Action("select-workspace", &Actions::selectWorkspace, &Validators::existWorkspaces);
    118     action->prompts()->push_back(new Prompt("workspace : ",
    119                  &Binder::queryWorkspacesForPattern));
    120     (*actionBindings)["select-workspace"] = action;
    121 
    122     action = new Action("select-client",
    123             &Actions::selectClient, &Validators::validateSelectClient);
    124     action->prompts()->push_back(new Prompt("client : ",
    125                  &Binder::queryClientsForPattern));
    126     (*actionBindings)["select-client"] = action;
    127 
    128     action = new Action("select-client-id",
    129             &Actions::selectClientId, &Validators::validateSelectClient);
    130     action->prompts()->push_back(new Prompt("client id: ",
    131                  &Binder::queryClientIdsForPattern));
    132     (*actionBindings)["select-client-id"] = action;
    133 
    134     (*actionBindings)["hook-client"] = new Action("hook-client", &Actions::hookClient, &Validators::validateHookClient);
    135     (*actionBindings)["unhook-client"] = new Action("unhook-client", &Actions::unhookClient, &Validators::validateUnhookClient);
    136 
    137     (*actionBindings)["cycle-client-prev"] = new Action("cycle-client-prev", &Actions::cycleClientPrev, &Validators::existClients);
    138     (*actionBindings)["cycle-workspace-prev"] = new Action("cycle-workspace-prev", &Actions::cycleWorkspacePrev, &Validators::existWorkspaces);
    139     (*actionBindings)["split-frame-left"] = new Action("split-frame-left", &Actions::splitFrameLeft, &Validators::existClientsWithinFrame);
    140     (*actionBindings)["split-frame-right"] = new Action("split-frame-right", &Actions::splitFrameRight, &Validators::existClientsWithinFrame);
    141     (*actionBindings)["split-frame-up"] = new Action("split-frame-up", &Actions::splitFrameUp, &Validators::existClientsWithinFrame);
    142     (*actionBindings)["split-frame-down"] = new Action("split-frame-down", &Actions::splitFrameDown, &Validators::existClientsWithinFrame);
    143     (*actionBindings)["join-frame-left"] = new Action("join-frame-left", &Actions::joinFrameLeft, &Validators::existsFrameLeft);
    144     (*actionBindings)["join-frame-right"] = new Action("join-frame-right", &Actions::joinFrameRight, &Validators::existsFrameRight);
    145     (*actionBindings)["join-frame-up"] = new Action("join-frame-up", &Actions::joinFrameUp, &Validators::existsFrameUp);
    146     (*actionBindings)["join-frame-down"] = new Action("join-frame-down", &Actions::joinFrameDown, &Validators::existsFrameDown);
    147     (*actionBindings)["send-client-left"] = new Action("send-client-left", &Actions::sendClientLeft, &Validators::existsFrameLeft);
    148     (*actionBindings)["send-client-right"] = new Action("send-client-right", &Actions::sendClientRight, &Validators::existsFrameRight);
    149     (*actionBindings)["send-client-up"] = new Action("send-client-up", &Actions::sendClientUp, &Validators::existsFrameUp);
    150     (*actionBindings)["send-client-down"] = new Action("send-client-down", &Actions::sendClientDown, &Validators::existsFrameDown);
    151     (*actionBindings)["detach-all-clients"] = new Action("detach-all-clients", &Actions::detachAllClients, &Validators::existClients);
    152     (*actionBindings)["attach-all-clients"] = new Action("attach-all-clients", &Actions::attachAllClients, &Validators::existDetachedClients);
    153     (*actionBindings)["detach-client"] = new Action("detach-client", &Actions::detachClient, &Validators::isClientFocused);
    154     (*actionBindings)["attach-last-client"] = new Action("attach-last-client", &Actions::attachLastClient, &Validators::existsDetachedClient);
    155     (*actionBindings)["inputmode"] = new Action("inputmode", &Actions::inputMode, &Validators::validateInputMode);
    156 
    157     action = new Action("attach-client",
    158             &Actions::attachClient, &Validators::existDetachedClients);
    159     action->prompts()->push_back(new Prompt("client : ",
    160                  &Binder::queryDetachedClientsForPattern));
    161     (*actionBindings)["attach-client"] = action;
    162 
    163     action = new Action("create-action", &Actions::createAction,
    164                         &Validators::isAlwaysPossible);
    165     action->prompts()->push_back(new Prompt("command : ", &Binder::queryCommandForPattern));
    166     action->prompts()->push_back(new Prompt("action name : ", 0));
    167     (*actionBindings)["create-action"] = action;
    168 
    169     action = new Action("create-workspace", &Actions::createWorkspace, &Validators::isAlwaysPossible);
    170     action->prompts()->push_back(new Prompt("workspace name : ", 0));
    171     (*actionBindings)["create-workspace"] = action;
    172 
    173     (*actionBindings)["destroy-frame"] = new Action("destroy-frame", &Actions::destroyFrame, &Validators::validateDestroyFrame);
    174     (*actionBindings)["destroy-workspace"] = new Action("destroy-workspace", &Actions::destroyWorkspace, &Validators::validateDestroyWorkspace);
    175 
    176     action = new Action("bind-shortcut", &Actions::bindShortcut,
    177             &Validators::isAlwaysPossible);
    178     action->prompts()->push_back(new Prompt("action to bind : ",
    179                 &Binder::queryActionKeysWithoutValidationForPattern));
    180     action->prompts()->push_back(new Prompt("keys <modifier>+<key> : ", 0));
    181     (*actionBindings)["bind-shortcut"] = action;
    182 
    183     action = new Action("rename-workspace", &Actions::renameWorkspace, &Validators::isWorkspaceFocused);
    184     action->prompts()->push_back(new Prompt("new name : ", 0));
    185     (*actionBindings)["rename-workspace"] = action;
    186 
    187     (*actionBindings)["select-frame-left"] = new Action("select-frame-left", &Actions::selectFrameLeft, &Validators::existsFrameLeft);
    188     (*actionBindings)["select-frame-right"] = new Action("select-frame-right", &Actions::selectFrameRight, &Validators::existsFrameRight);
    189     (*actionBindings)["select-frame-up"] = new Action("select-frame-up", &Actions::selectFrameUp, &Validators::existsFrameUp);
    190     (*actionBindings)["select-frame-down"] = new Action("select-frame-down", &Actions::selectFrameDown, &Validators::existsFrameDown);
    191 
    192     (*actionBindings)["swap-frame-left"] = new Action("swap-frame-left", &Actions::swapFrameLeft, &Validators::existsFrameLeft);
    193     (*actionBindings)["swap-frame-right"] = new Action("swap-frame-right", &Actions::swapFrameRight, &Validators::existsFrameRight);
    194     (*actionBindings)["swap-frame-up"] = new Action("swap-frame-up", &Actions::swapFrameUp, &Validators::existsFrameUp);
    195     (*actionBindings)["swap-frame-down"] = new Action("swap-frame-down", &Actions::swapFrameDown, &Validators::existsFrameDown);
    196 
    197     (*actionBindings)["swap-client-left"] = new Action("swap-client-left", &Actions::swapClientLeft, &Validators::existsFrameLeft);
    198     (*actionBindings)["swap-client-right"] = new Action("swap-client-right", &Actions::swapClientRight, &Validators::existsFrameRight);
    199     (*actionBindings)["swap-client-up"] = new Action("swap-client-up", &Actions::swapClientUp, &Validators::existsFrameUp);
    200     (*actionBindings)["swap-client-down"] = new Action("swap-client-down", &Actions::swapClientDown, &Validators::existsFrameDown);
    201 
    202     (*actionBindings)["toggle-max"] = new Action("toggle-max", &Actions::toggleMaximization, &Validators::isFrameOrClientFrameFocused);
    203 
    204     (*actionBindings)["raise"] = new Action("raise", &Actions::raise, &Validators::isClientFocused);
    205     (*actionBindings)["lower"] = new Action("lower", &Actions::lower, &Validators::isClientFocused);
    206     (*actionBindings)["fit-client"] = new Action("fit-client", &Actions::fitClient, &Validators::isClientFocused);
    207     (*actionBindings)["banish"] = new Action("banish", &Actions::banish, &Validators::isAlwaysPossible);
    208     (*actionBindings)["toggle-clientbar-mode"] = new Action("toggle-clientbar-mode", &Actions::toggleClientBarMode, &Validators::isAlwaysPossible);
    209     (*actionBindings)["toggle-sloppy-mode"] = new Action("toggle-sloppy-mode", &Actions::toggleSloppyMode, &Validators::isAlwaysPossible);
    210     (*actionBindings)["toggle-shortcuts"] = new Action("toggle-shortcuts", &Actions::toggleShortcuts, &Validators::isAlwaysPossible);
    211     (*actionBindings)["grab-move"] = new Action("grab-move", &Actions::grabMove, &Validators::isClientFrameFocused);
    212     (*actionBindings)["toggle-tiled"] = new Action("toggle-tiled", &Actions::toggleTiled, &Validators::existClientsWithinFrame);
    213     (*actionBindings)["zoom-client"] = new Action("zoom-client", &Actions::zoomClient, &Validators::existClientsWithinFrame);
    214 
    215 }
    216 
    217 void Actions::selectFrameLeft(Action *caller, const char *argument) {
    218 
    219     Monitor *monitor = KERNEL->focusedMonitor();
    220     Workspace *workspace = monitor->focused();
    221     assert(workspace);
    222 
    223     workspace->selectFrame(LEFT);
    224 }
    225 
    226 void Actions::selectFrameRight(Action *caller, const char *argument) {
    227 
    228     Monitor *monitor = KERNEL->focusedMonitor();
    229     Workspace *workspace = monitor->focused();
    230     assert(workspace);
    231 
    232     workspace->selectFrame(RIGHT);
    233 }
    234 
    235 void Actions::selectFrameUp(Action *caller, const char *argument) {
    236 
    237     Monitor *monitor = KERNEL->focusedMonitor();
    238     Workspace *workspace = monitor->focused();
    239     assert(workspace);
    240 
    241     workspace->selectFrame(UP);
    242 }
    243 
    244 void Actions::selectFrameDown(Action *caller, const char *argument) {
    245 
    246     Monitor *monitor = KERNEL->focusedMonitor();
    247     Workspace *workspace = monitor->focused();
    248     assert(workspace);
    249 
    250     workspace->selectFrame(DOWN);
    251 }
    252 
    253 void Actions::toggleShortcuts(Action *caller, const char *argument) {
    254     KERNEL->toggleShortcuts();
    255 }
    256 
    257 void Actions::restart(Action *caller, const char *argument) {
    258     KERNEL->restart();
    259 }
    260 
    261 void Actions::quit(Action *caller, const char *argument) {
    262     KERNEL->stop();
    263 }
    264 
    265 void Actions::saveSettings(Action *caller, const char *argument) {
    266     KERNEL->saveSettings();
    267 }
    268 
    269 void Actions::execute(Action *caller, const char *command) {
    270 
    271     Launcher::instance()->exec(command);
    272 }
    273 
    274 void Actions::executeTerm(Action *caller, const char *command) {
    275     MSettings *commonSettings = KERNEL->commonSettings();
    276     string cmd = Util::get(commonSettings, (string)"terminal") + " " + command;
    277 
    278     Launcher::instance()->exec(cmd);
    279 }
    280 
    281 void Actions::cycleClientNext(Action *caller, const char *argument) {
    282     Monitor *monitor = KERNEL->focusedMonitor();
    283     Workspace *workspace = monitor->focused();
    284     assert(workspace);
    285 
    286     workspace->cycleClientNext();
    287 }
    288 
    289 void Actions::cycleClientPrev(Action *caller, const char *argument) {
    290     Monitor *monitor = KERNEL->focusedMonitor();
    291     Workspace *workspace = monitor->focused();
    292     assert(workspace);
    293 
    294     workspace->cycleClientPrev();
    295 }
    296 
    297 void Actions::attachAllClients(Action *caller, const char *argument) {
    298     Monitor *monitor = KERNEL->focusedMonitor();
    299     monitor->attachAllClients();
    300 }
    301 
    302 void Actions::detachAllClients(Action *caller, const char *argument) {
    303     Monitor *monitor = KERNEL->focusedMonitor();
    304     monitor->detachAllClients();
    305 }
    306 
    307 void Actions::detachClient(Action *caller, const char *argument) {
    308     Monitor *monitor = KERNEL->focusedMonitor();
    309     monitor->detachClient();
    310 }
    311 
    312 #ifdef SLOT_SUPPORT
    313 void Actions::unslotClient(Action *caller, const char *argument) {
    314     Monitor *monitor = KERNEL->focusedMonitor();
    315     assert(monitor != 0);
    316 
    317     monitor->unslotClient();
    318 }
    319 
    320 void Actions::slotClient(Action *caller, const char *argument) {
    321     Monitor *monitor = KERNEL->focusedMonitor();
    322     assert(monitor != 0);
    323 
    324     monitor->slotClient();
    325 }
    326 
    327 void Actions::toggleSlot(Action *caller, const char *argument) {
    328 
    329     Monitor *monitor = KERNEL->focusedMonitor();
    330     assert(monitor != 0);
    331 
    332     monitor->toggleSlot();
    333 }
    334 
    335 void Actions::cycleSlotTabNext(Action *caller, const char *argument) {
    336 
    337     Monitor *monitor = KERNEL->focusedMonitor();
    338     monitor->cycleSlotTabNext();
    339 }
    340 
    341 void Actions::cycleSlotTabPrev(Action *caller, const char *argument) {
    342 
    343     Monitor *monitor = KERNEL->focusedMonitor();
    344     monitor->cycleSlotTabPrev();
    345 }
    346 
    347 void Actions::killSlotClient(Action *caller, const char *argument) {
    348 
    349     Monitor *monitor = KERNEL->focusedMonitor();
    350     KERNEL->killClient(monitor->slot()->focused()->focused());
    351 }
    352 
    353 #endif // SLOT_SUPPORT
    354 
    355 void Actions::attachClient(Action *caller, const char *argument) {
    356     Monitor *monitor = KERNEL->focusedMonitor();
    357 
    358     monitor->attachClientByName(argument);
    359 }
    360 
    361 void Actions::attachLastClient(Action *caller, const char *argument) {
    362     Monitor *monitor = KERNEL->focusedMonitor();
    363 
    364     monitor->attachLastClient();
    365 }
    366 
    367 void Actions::toggleClientSticky(Action *caller, const char *argument) {
    368     Monitor *monitor = KERNEL->focusedMonitor();
    369     Workspace *workspace = monitor->focused();
    370     assert(workspace);
    371 
    372     workspace->toggleClientSticky();
    373 }
    374 
    375 void Actions::toggleClientMode(Action *caller, const char *argument) {
    376     Monitor *monitor = KERNEL->focusedMonitor();
    377     Workspace *workspace = monitor->focused();
    378     assert(workspace);
    379 
    380     workspace->toggleClientMode();
    381 }
    382 
    383 void Actions::toggleMode(Action *caller, const char *argument) {
    384     Monitor *monitor = KERNEL->focusedMonitor();
    385     Workspace *workspace = monitor->focused();
    386 
    387     workspace->toggleMode();
    388 }
    389 
    390 void Actions::cycleWorkspaceNext(Action *caller, const char *argument) {
    391 
    392     Monitor *monitor = KERNEL->focusedMonitor();
    393     assert(monitor != 0);
    394 
    395     monitor->focus(monitor->next());
    396 }
    397 
    398 void Actions::cycleWorkspacePrev(Action *caller, const char *argument) {
    399 
    400     Monitor *monitor = KERNEL->focusedMonitor();
    401     assert(monitor != 0);
    402 
    403     monitor->focus(monitor->prev());
    404 }
    405 
    406 void Actions::growLeft(Action *caller, const char *argument) {
    407 
    408     Monitor *monitor = KERNEL->focusedMonitor();
    409     Workspace *workspace = monitor->focused();
    410     Thing *thing = workspace->focusedThing();
    411     assert(thing);
    412 
    413     workspace->resize(thing, LEFT, true);
    414 }
    415 
    416 void Actions::growRight(Action *caller, const char *argument) {
    417 
    418     Monitor *monitor = KERNEL->focusedMonitor();
    419     Workspace *workspace = monitor->focused();
    420     Thing *thing = workspace->focusedThing();
    421     assert(thing);
    422 
    423     workspace->resize(thing, RIGHT, true);
    424 }
    425 
    426 void Actions::growUp(Action *caller, const char *argument) {
    427 
    428     Monitor *monitor = KERNEL->focusedMonitor();
    429     Workspace *workspace = monitor->focused();
    430     Thing *thing = workspace->focusedThing();
    431     assert(thing);
    432 
    433     workspace->resize(thing, UP, true);
    434 }
    435 
    436 void Actions::growDown(Action *caller, const char *argument) {
    437 
    438     Monitor *monitor = KERNEL->focusedMonitor();
    439     Workspace *workspace = monitor->focused();
    440     Thing *thing = workspace->focusedThing();
    441     assert(thing);
    442 
    443     workspace->resize(thing, DOWN, true);
    444 }
    445 
    446 void Actions::shrinkLeft(Action *caller, const char *argument) {
    447 
    448     Monitor *monitor = KERNEL->focusedMonitor();
    449     Workspace *workspace = monitor->focused();
    450     Thing *thing = workspace->focusedThing();
    451     assert(thing);
    452 
    453     workspace->resize(thing, LEFT, false);
    454 }
    455 
    456 void Actions::shrinkRight(Action *caller, const char *argument) {
    457 
    458     Monitor *monitor = KERNEL->focusedMonitor();
    459     Workspace *workspace = monitor->focused();
    460     Thing *thing = workspace->focusedThing();
    461     assert(thing);
    462 
    463     workspace->resize(thing, RIGHT, false);
    464 }
    465 
    466 void Actions::shrinkUp(Action *caller, const char *argument) {
    467 
    468     Monitor *monitor = KERNEL->focusedMonitor();
    469     Workspace *workspace = monitor->focused();
    470     Thing *thing = workspace->focusedThing();
    471     assert(thing);
    472 
    473     workspace->resize(thing, UP, false);
    474 }
    475 
    476 void Actions::shrinkDown(Action *caller, const char *argument) {
    477 
    478     Monitor *monitor = KERNEL->focusedMonitor();
    479     Workspace *workspace = monitor->focused();
    480     Thing *thing = workspace->focusedThing();
    481     assert(thing);
    482 
    483     workspace->resize(thing, DOWN, false);
    484 }
    485 
    486 void Actions::moveClientLeft(Action *caller, const char *argument) {
    487 
    488     Monitor *monitor = KERNEL->focusedMonitor();
    489     Workspace *workspace = monitor->focused();
    490     assert(workspace);
    491 
    492     Client *client = monitor->focusedClient();
    493     if (client) {
    494         workspace->moveClient(LEFT);
    495     }
    496 }
    497 
    498 void Actions::moveClientRight(Action *caller, const char *argument) {
    499 
    500     Monitor *monitor = KERNEL->focusedMonitor();
    501     Workspace *workspace = monitor->focused();
    502     assert(workspace);
    503 
    504     Client *client = monitor->focusedClient();
    505     if (client) {
    506         workspace->moveClient(RIGHT);
    507     }
    508 }
    509 
    510 void Actions::moveClientUp(Action *caller, const char *argument) {
    511 
    512     Monitor *monitor = KERNEL->focusedMonitor();
    513     Workspace *workspace = monitor->focused();
    514     assert(workspace);
    515 
    516     Client *client = monitor->focusedClient();
    517     if (client) {
    518         workspace->moveClient(UP);
    519     }
    520 }
    521 
    522 void Actions::moveClientDown(Action *caller, const char *argument) {
    523 
    524     Monitor *monitor = KERNEL->focusedMonitor();
    525     Workspace *workspace = monitor->focused();
    526     assert(workspace);
    527 
    528     Client *client = monitor->focusedClient();
    529     if (client) {
    530         workspace->moveClient(DOWN);
    531     }
    532 }
    533 
    534 void Actions::sendClientLeft(Action *caller, const char *argument) {
    535 
    536     Monitor *monitor = KERNEL->focusedMonitor();
    537     Workspace *workspace = monitor->focused();
    538     assert(workspace);
    539 
    540     Client *client = monitor->focusedClient();
    541     if (client) {
    542         workspace->sendClient(LEFT);
    543     }
    544 }
    545 
    546 void Actions::sendClientRight(Action *caller, const char *argument) {
    547 
    548     Monitor *monitor = KERNEL->focusedMonitor();
    549     Workspace *workspace = monitor->focused();
    550     assert(workspace);
    551 
    552     Client *client = monitor->focusedClient();
    553     if (client) {
    554         workspace->sendClient(RIGHT);
    555     }
    556 }
    557 
    558 void Actions::sendClientUp(Action *caller, const char *argument) {
    559 
    560     Monitor *monitor = KERNEL->focusedMonitor();
    561     Workspace *workspace = monitor->focused();
    562     assert(workspace);
    563 
    564     Client *client = monitor->focusedClient();
    565     if (client) {
    566         workspace->sendClient(UP);
    567     }
    568 }
    569 
    570 void Actions::sendClientDown(Action *caller, const char *argument) {
    571 
    572     Monitor *monitor = KERNEL->focusedMonitor();
    573     Workspace *workspace = monitor->focused();
    574     assert(workspace);
    575 
    576     Client *client = monitor->focusedClient();
    577     if (client) {
    578         workspace->sendClient(DOWN);
    579     }
    580 }
    581 
    582 void Actions::joinFrameLeft(Action *caller, const char *argument) {
    583 
    584     Monitor *monitor = KERNEL->focusedMonitor();
    585     Workspace *workspace = monitor->focused();
    586     assert(workspace);
    587 
    588     workspace->joinFrame(LEFT);
    589 }
    590 
    591 void Actions::joinFrameRight(Action *caller, const char *argument) {
    592 
    593     Monitor *monitor = KERNEL->focusedMonitor();
    594     Workspace *workspace = monitor->focused();
    595     assert(workspace);
    596 
    597     workspace->joinFrame(RIGHT);
    598 }
    599 
    600 void Actions::joinFrameUp(Action *caller, const char *argument) {
    601 
    602     Monitor *monitor = KERNEL->focusedMonitor();
    603     Workspace *workspace = monitor->focused();
    604     assert(workspace);
    605 
    606     workspace->joinFrame(UP);
    607 }
    608 
    609 void Actions::joinFrameDown(Action *caller, const char *argument) {
    610 
    611     Monitor *monitor = KERNEL->focusedMonitor();
    612     Workspace *workspace = monitor->focused();
    613     assert(workspace);
    614 
    615     workspace->joinFrame(DOWN);
    616 }
    617 
    618 void Actions::splitFrameLeft(Action *caller, const char *argument) {
    619 
    620     Monitor *monitor = KERNEL->focusedMonitor();
    621     Workspace *workspace = monitor->focused();
    622     assert(workspace);
    623 
    624     workspace->splitFrame(LEFT);
    625 }
    626 
    627 void Actions::splitFrameRight(Action *caller, const char *argument) {
    628 
    629     Monitor *monitor = KERNEL->focusedMonitor();
    630     Workspace *workspace = monitor->focused();
    631     assert(workspace);
    632 
    633     workspace->splitFrame(RIGHT);
    634 }
    635 
    636 void Actions::splitFrameUp(Action *caller, const char *argument) {
    637 
    638     Monitor *monitor = KERNEL->focusedMonitor();
    639     Workspace *workspace = monitor->focused();
    640     assert(workspace);
    641 
    642     workspace->splitFrame(UP);
    643 }
    644 
    645 void Actions::splitFrameDown(Action *caller, const char *argument) {
    646 
    647     Monitor *monitor = KERNEL->focusedMonitor();
    648     Workspace *workspace = monitor->focused();
    649     assert(workspace);
    650 
    651     workspace->splitFrame(DOWN);
    652 }
    653 
    654 void Actions::showBorders(Action *caller, const char *argument) {
    655 
    656     Monitor *monitor = KERNEL->focusedMonitor();
    657     Workspace *workspace = monitor->focused();
    658     assert(workspace);
    659 
    660     workspace->toggleBorders(true);
    661 }
    662 
    663 void Actions::hideBorders(Action *caller, const char *argument) {
    664 
    665     Monitor *monitor = KERNEL->focusedMonitor();
    666     Workspace *workspace = monitor->focused();
    667     assert(workspace);
    668 
    669     workspace->toggleBorders(false);
    670 }
    671 
    672 void Actions::toggleBorder(Action *caller, const char *argument) {
    673 
    674     Monitor *monitor = KERNEL->focusedMonitor();
    675     Workspace *workspace = monitor->focused();
    676     assert(workspace);
    677 
    678     Thing *thing = workspace->focusedThing();
    679     if (thing) {
    680         if (thing->borderWidth()) {
    681             thing->setBorderWidth(0);
    682         }
    683         else {
    684             thing->setBorderWidth(KERNEL->borderWidth());
    685         }
    686         thing->resize();
    687     }
    688 }
    689 
    690 void Actions::showBars(Action *caller, const char *argument) {
    691 
    692     Monitor *monitor = KERNEL->focusedMonitor();
    693     Workspace *workspace = monitor->focused();
    694     assert(workspace);
    695 
    696     workspace->toggleBars(true);
    697 }
    698 
    699 void Actions::hideBars(Action *caller, const char *argument) {
    700 
    701     Monitor *monitor = KERNEL->focusedMonitor();
    702     Workspace *workspace = monitor->focused();
    703     assert(workspace);
    704 
    705     workspace->toggleBars(false);
    706 }
    707 
    708 void Actions::toggleBar(Action *caller, const char *argument) {
    709 
    710     Monitor *monitor = KERNEL->focusedMonitor();
    711     Workspace *workspace = monitor->focused();
    712     assert(workspace);
    713 
    714     Thing *thing = workspace->focusedThing();
    715     if (thing) {
    716         thing->setTitleBarHeight(thing->titleBarHeight() ? 
    717                                  0 : monitor->titleBarHeight());
    718         thing->resize();
    719     }
    720 }
    721 
    722 void Actions::toggleClientBar(Action *caller, const char *argument) {
    723 
    724     Monitor *monitor = KERNEL->focusedMonitor();
    725     assert(monitor != 0);
    726 
    727     monitor->toggleClientBar();
    728 }
    729 
    730 void Actions::toggleStatusBar(Action *caller, const char *argument) {
    731 
    732     Monitor *monitor = KERNEL->focusedMonitor();
    733     assert(monitor != 0);
    734 
    735     monitor->toggleStatusBar();
    736 }
    737 
    738 void Actions::inputMode(Action *caller, const char *argument) {
    739 
    740     Monitor *monitor = KERNEL->focusedMonitor();
    741     assert(monitor != 0);
    742 
    743     monitor->inputBar()->runKey(KERNEL->defaultPrompt());
    744 }
    745 
    746 void Actions::killClient(Action *caller, const char *argument) {
    747 
    748     KERNEL->killClient(KERNEL->focusedClient());
    749 }
    750 
    751 void Actions::sequence(Action *caller, const char *command) {
    752 
    753     Launcher::instance()->execSeq(caller, command);
    754 }
    755 
    756 void Actions::createAction(Action *caller, const char *argument) {
    757 
    758     string arg = argument;
    759     LOGDEBUG("arg: " + arg);
    760     unsigned int argDelim = arg.find_last_of('+');
    761     if (argDelim == string::npos) {
    762         return;
    763     }
    764     string cmd = arg.substr(0, argDelim);
    765     string bind = arg.substr(argDelim + 1);
    766 
    767     if ((bind.length() < 1) || (cmd.length() < 1)) {
    768         return;
    769     }
    770     Action *action = new Action(bind, &Actions::execute,
    771                                 &Validators::isWorkspaceFocused, Action::EXTERN,
    772                                 (char *)cmd.c_str());
    773     (*KERNEL->actionBindings())[bind] = action;
    774     (*KERNEL->actionSettings())["extern." + action->id() + ".cmd"] = cmd;
    775 }
    776 
    777 void Actions::createWorkspace(Action *caller, const char *argument) {
    778 
    779     assert(argument != 0);
    780 
    781     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    782 
    783     focusedMonitor->createNewWorkspace(argument);
    784 }
    785 
    786 
    787 void Actions::bindShortcut(Action *caller, const char *argument) {
    788 
    789     KERNEL->bindShortcut(argument);
    790 }
    791 
    792 // TODO: ungrab potentially keys before removing
    793 void Actions::destroyAction(Action *caller, const char *argument) {
    794 
    795     Action *action = Util::get(KERNEL->actionBindings(), argument);
    796     if (action && (action->type() != Action::INTERN)) {
    797 
    798         Util::remove(KERNEL->actionBindings(), argument);
    799         string prefix = (action->type() == Action::EXTERN) ? "extern." :
    800             "chain.";
    801         prefix += argument;
    802         Util::remove(KERNEL->actionSettings(), prefix);
    803     }
    804 }
    805 
    806 void Actions::destroyWorkspace(Action *caller, const char *argument) {
    807     Monitor *monitor = KERNEL->focusedMonitor();
    808     assert(monitor != 0);
    809 
    810     monitor->destroyWorkspace(monitor->focused());
    811 }
    812 
    813 void Actions::selectMonitor(Action *caller, const char *argument) {
    814 
    815     KERNEL->selectMonitor(argument);
    816 }
    817 
    818 void Actions::selectWorkspace(Action *caller, const char *argument) {
    819 
    820     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    821     Workspace *workspace = focusedMonitor->workspaceForName(argument);
    822     if (workspace) {
    823         focusedMonitor->focus(workspace);
    824     }
    825 }
    826 
    827 void Actions::selectClientId(Action *caller, const char *argument) {
    828 
    829     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    830 
    831     focusedMonitor->focusClientById(argument);
    832 }
    833 
    834 void Actions::selectClient(Action *caller, const char *argument) {
    835 
    836     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    837 
    838     focusedMonitor->focusClientByName(argument);
    839 }
    840 
    841 void Actions::renameWorkspace(Action *caller, const char *argument) {
    842 
    843     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    844     assert(focusedMonitor != 0);
    845 
    846     focusedMonitor->renameWorkspace(focusedMonitor->focused(),
    847                                     argument);
    848 }
    849 
    850 void Actions::swapFrameLeft(Action *caller, const char *argument) {
    851 
    852     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    853     Workspace *workspace = focusedMonitor->focused();
    854     assert(workspace);
    855 
    856     workspace->swapFrame(LEFT);
    857 }
    858 
    859 void Actions::swapFrameRight(Action *caller, const char *argument) {
    860 
    861     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    862     Workspace *workspace = focusedMonitor->focused();
    863     assert(workspace);
    864 
    865     workspace->swapFrame(RIGHT);
    866 }
    867 
    868 void Actions::swapFrameUp(Action *caller, const char *argument) {
    869 
    870     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    871     Workspace *workspace = focusedMonitor->focused();
    872     assert(workspace);
    873 
    874     workspace->swapFrame(UP);
    875 }
    876 
    877 void Actions::swapFrameDown(Action *caller, const char *argument) {
    878 
    879     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    880     Workspace *workspace = focusedMonitor->focused();
    881     assert(workspace);
    882 
    883     workspace->swapFrame(DOWN);
    884 }
    885 
    886 void Actions::swapClientLeft(Action *caller, const char *argument) {
    887 
    888     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    889     Workspace *workspace = focusedMonitor->focused();
    890     assert(workspace);
    891 
    892     workspace->swapClient(LEFT);
    893 }
    894 
    895 void Actions::swapClientRight(Action *caller, const char *argument) {
    896 
    897     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    898     Workspace *workspace = focusedMonitor->focused();
    899     assert(workspace);
    900 
    901     workspace->swapClient(RIGHT);
    902 }
    903 
    904 void Actions::swapClientUp(Action *caller, const char *argument) {
    905 
    906     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    907     Workspace *workspace = focusedMonitor->focused();
    908     assert(workspace);
    909 
    910     workspace->swapClient(UP);
    911 }
    912 
    913 void Actions::swapClientDown(Action *caller, const char *argument) {
    914 
    915     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    916     Workspace *workspace = focusedMonitor->focused();
    917     assert(workspace);
    918 
    919     workspace->swapClient(DOWN);
    920 }
    921 
    922 
    923 void Actions::toggleMaximization(Action *caller, const char *argument) {
    924     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    925 
    926     focusedMonitor->toggleThingMaximization();
    927 }
    928 
    929 void Actions::toggleClientBarMode(Action *caller, const char *argument) {
    930 
    931     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    932     ClientBar *clientBar = focusedMonitor->clientBar();
    933 
    934     clientBar->setMode((clientBar->mode() == ClientBar::PAGER) ?
    935                         ClientBar::CLIENTINFO : ClientBar::PAGER);
    936     clientBar->illuminate();
    937 }
    938 
    939 void Actions::fitClient(Action *caller, const char *argument) {
    940 
    941     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    942     Workspace *workspace = focusedMonitor->focused();
    943 
    944     workspace->fitClient();
    945 }
    946 
    947 void Actions::lower(Action *caller, const char *argument) {
    948 
    949     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    950     Workspace *workspace = focusedMonitor->focused();
    951 
    952     workspace->lower();
    953 }
    954 
    955 void Actions::raise(Action *caller, const char *argument) {
    956 
    957     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    958     Workspace *workspace = focusedMonitor->focused();
    959 
    960     workspace->raise();
    961 }
    962 
    963 void Actions::rehash(Action *caller, const char *argument) {
    964 
    965     Expander::instance()->rehash();
    966 }
    967 
    968 void Actions::beginChainRecord(Action *caller, const char *argument) {
    969     KERNEL->beginRecording();
    970 }
    971 
    972 void Actions::endChainRecord(Action *caller, const char *argument) {
    973     KERNEL->endChainRecording(argument);
    974 }
    975 
    976 void Actions::endScriptRecord(Action *caller, const char *argument) {
    977     KERNEL->endScriptRecording(argument);
    978 }
    979 
    980 void Actions::cancelRecord(Action *caller, const char *argument) {
    981     KERNEL->cancelRecording();
    982 }
    983 
    984 void Actions::banish(Action *caller, const char *argument) {
    985     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    986     focusedMonitor->banish();
    987 }
    988 
    989 void Actions::unhookClient(Action *caller, const char *argument) {
    990     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    991 
    992     focusedMonitor->unhookClient();
    993 }
    994 
    995 void Actions::hookClient(Action *caller, const char *argument) {
    996     Monitor *focusedMonitor = KERNEL->focusedMonitor();
    997 
    998     focusedMonitor->hookClient();
    999 }
   1000 
   1001 void Actions::toggleSloppyMode(Action *caller, const char *argument) {
   1002     KERNEL->toggleSloppyMode();
   1003 }
   1004 
   1005 void Actions::grabMove(Action *caller, const char *argument) {
   1006     KERNEL->grabMove();
   1007 }
   1008 
   1009 void Actions::zoomClient(Action *caller, const char *argument) {
   1010     Monitor *monitor = KERNEL->focusedMonitor();
   1011     Workspace *workspace = monitor->focused(); 
   1012     Frame *frame = workspace->focusedFrame();
   1013 
   1014     if (frame) {
   1015         frame->zoomClient();
   1016     }
   1017 }
   1018 
   1019 void Actions::toggleTiled(Action *caller, const char *argument) {
   1020     Monitor *monitor = KERNEL->focusedMonitor();
   1021     Workspace *workspace = monitor->focused();
   1022     Frame *frame = workspace->focusedFrame();
   1023     if (frame) {
   1024         frame->toggleTiled();
   1025     }
   1026 }
   1027 
   1028 void Actions::destroyFrame(Action *caller, const char *argument) {
   1029     Monitor *monitor = KERNEL->focusedMonitor();
   1030     Workspace *workspace = monitor->focused();
   1031 
   1032     if (workspace->focusedFrame()) {
   1033         workspace->destroyFrame(workspace->focusedFrame());
   1034     }
   1035 }