X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=util%2Fepist%2Fscreen.cc;h=64dccf797f54605e22eb7b9bc5b8fd3bda14b5a8;hb=7d67f8557b3254aeb370a995f417c86606e8a67d;hp=8597e5953d2df2392a7c4aaea8f510cf866b6835;hpb=6a8f5f44e123c9ade7964e2051dd0d6a9858961c;p=chaz%2Fopenbox diff --git a/util/epist/screen.cc b/util/epist/screen.cc index 8597e595..64dccf79 100644 --- a/util/epist/screen.cc +++ b/util/epist/screen.cc @@ -25,6 +25,10 @@ #endif // HAVE_CONFIG_H extern "C" { +#ifdef HAVE_STDIO_H +# include +#endif // HAVE_STDIO_H + #ifdef HAVE_UNISTD_H # include # include @@ -40,6 +44,7 @@ using std::hex; using std::dec; using std::string; +#include "../../src/BaseDisplay.hh" #include "../../src/XAtom.hh" #include "screen.hh" #include "epist.hh" @@ -50,7 +55,8 @@ screen::screen(epist *epist, int number) { _xatom = _epist->xatom(); _number = number; _active = _clients.end(); - _root = RootWindow(_epist->getXDisplay(), _number); + _info = _epist->getScreenInfo(_number); + _root = _info->getRootWindow(); // find a window manager supporting NETWM, waiting for it to load if we must int count = 20; // try for 20 seconds @@ -198,6 +204,13 @@ void screen::handleKeypress(const XEvent &e) { case Action::changeWorkspace: changeWorkspace(it->number()); return; + + case Action::execute: + execCommand(it->string()); + return; + + default: + break; } // these actions require an active window @@ -221,7 +234,7 @@ void screen::handleKeypress(const XEvent &e) { window->lower(); return; - case Action::sendTo: + case Action::sendToWorkspace: window->sendTo(it->number()); return; @@ -235,6 +248,10 @@ void screen::handleKeypress(const XEvent &e) { case Action::toggleshade: window->shade(! window->shaded()); return; + + default: + assert(false); // unhandled action type! + break; } } } @@ -349,14 +366,30 @@ void screen::updateActiveWindow() { else cout << "0x" << hex << (*_active)->window() << dec << endl; } -/* - * use this when execing a command to have it on the right screen - string dtmp = (string)"DISPLAY=" + display_name; - if (putenv(const_cast(dtmp.c_str()))) { - cout << "warning: couldn't set environment variable 'DISPLAY'\n"; - perror("putenv()"); - } - */ + +void screen::execCommand(const std::string &cmd) const { + pid_t pid; + if ((pid = fork()) == 0) { + extern char **environ; + + char *const argv[] = { + "sh", + "-c", + const_cast(cmd.c_str()), + 0 + }; + // make the command run on the correct screen + if (putenv(const_cast(_info->displayString().c_str()))) { + cout << "warning: couldn't set environment variable 'DISPLAY'\n"; + perror("putenv()"); + } + execve("/bin/sh", argv, environ); + exit(127); + } else if (pid == -1) { + cout << _epist->getApplicationName() << + ": Could not fork a process for executing a command\n"; + } +} void screen::cycleWindow(const bool forward, const bool alldesktops, @@ -367,6 +400,10 @@ void screen::cycleWindow(const bool forward, const bool alldesktops, WindowList::const_iterator target = _active; + string classname; + if (sameclass && target != _clients.end()) + classname = (*target)->appClass(); + if (target == _clients.end()) target = _clients.begin(); @@ -383,8 +420,8 @@ void screen::cycleWindow(const bool forward, const bool alldesktops, } while (target == _clients.end() || (*target)->iconic() || (! alldesktops && (*target)->desktop() != _active_desktop) || - (sameclass && _active != _clients.end() && - (*target)->appClass() != (*_active)->appClass())); + (sameclass && ! classname.empty() && + (*target)->appClass() != classname)); if (target != _clients.end()) (*target)->focus();