]> Dogcows Code - chaz/openbox/blobdiff - util/epist/screen.cc
make cycling by window class work properly, was using the app name instead of class
[chaz/openbox] / util / epist / screen.cc
index 72ee34352dea39616dea96de51902664a0ec68fa..64dccf797f54605e22eb7b9bc5b8fd3bda14b5a8 100644 (file)
 #endif // HAVE_CONFIG_H
 
 extern "C" {
+#ifdef    HAVE_STDIO_H
+#  include <stdio.h>
+#endif // HAVE_STDIO_H
+
 #ifdef    HAVE_UNISTD_H
 #  include <sys/types.h>
 #  include <unistd.h>
@@ -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
@@ -164,11 +170,11 @@ void screen::handleKeypress(const XEvent &e) {
         return;
 
       case Action::nextWindow:
-        cycleWindow(true, false);
+        cycleWindow(true);
         return;
 
       case Action::prevWindow:
-        cycleWindow(false, false);
+        cycleWindow(false);
         return;
 
       case Action::nextWindowOnAllWorkspaces:
@@ -179,9 +185,32 @@ void screen::handleKeypress(const XEvent &e) {
         cycleWindow(false, true);
         return;
 
+      case Action::nextWindowOfClass:
+        cycleWindow(true, false, true);
+        return;
+
+      case Action::prevWindowOfClass:
+        cycleWindow(false, false, true);
+        return;
+
+      case Action::nextWindowOfClassOnAllWorkspaces:
+        cycleWindow(true, true, true);
+        return;
+
+      case Action::prevWindowOfClassOnAllWorkspaces:
+        cycleWindow(false, true, true);
+        return;
+
       case Action::changeWorkspace:
         changeWorkspace(it->number());
         return;
+
+      case Action::execute:
+        execCommand(it->string());
+        return;
+
+      default:
+        break;
       }
 
       // these actions require an active window
@@ -205,9 +234,24 @@ void screen::handleKeypress(const XEvent &e) {
           window->lower();
           return;
 
+        case Action::sendToWorkspace:
+          window->sendTo(it->number());
+          return;
+
+        case Action::toggleomnipresent:
+          if (window->desktop() == 0xffffffff)
+            window->sendTo(_active_desktop);
+          else
+            window->sendTo(0xffffffff);
+          return;
+
         case Action::toggleshade:
           window->shade(! window->shaded());
           return;
+      
+        default:
+          assert(false);  // unhandled action type!
+          break;
         }
       }
     }
@@ -322,23 +366,44 @@ 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<char*>(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<char *>(cmd.c_str()),
+      0
+    };
+    // make the command run on the correct screen
+    if (putenv(const_cast<char*>(_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) const {
+
+void screen::cycleWindow(const bool forward, const bool alldesktops,
+                         const bool sameclass) const {
   assert(_managed);
 
   if (_clients.empty()) return;
     
   WindowList::const_iterator target = _active;
 
+  string classname;
+  if (sameclass && target != _clients.end())
+    classname = (*target)->appClass();
+
   if (target == _clients.end())
     target = _clients.begin();
  
@@ -354,7 +419,9 @@ void screen::cycleWindow(const bool forward, const bool alldesktops) const {
     }
   } while (target == _clients.end() ||
            (*target)->iconic() ||
-           (! alldesktops && (*target)->desktop() != _active_desktop));
+           (! alldesktops && (*target)->desktop() != _active_desktop) ||
+           (sameclass && ! classname.empty() &&
+            (*target)->appClass() != classname));
   
   if (target != _clients.end())
     (*target)->focus();
This page took 0.025191 seconds and 4 git commands to generate.