To access client window and client pid command line it should be
wrapped (as it is an environment variable). Taking a screenshot of
the current active window and then displaying it can be done with:
#!/bin/sh
import -window $CLIENT_WINDOW /tmp/client.$CLIENT_PID.png
display /tmp/client.$CLIENT_PID.png
And then an action executing the above script.
| configure.ac | |
| 258 | @@ -258,6 +258,7 @@ |
| 258 | |
| 259 | dnl Check for library functions |
| 260 | AC_CHECK_FUNC(setenv, [AC_DEFINE(HAVE_SETENV, [1], [Define to 1 if you the setenv systam call])], ) |
| 261 | AC_CHECK_FUNC(unsetenv, [AC_DEFINE(HAVE_UNSETENV, [1], [Define to 1 if you the unsetenv systam call])], ) |
| 262 | AC_CHECK_FUNC(swprintf, [AC_DEFINE(HAVE_SWPRINTF, [1], [Define to 1 if you have swprintf])], ) |
| 263 | |
| 264 | dnl Check whether time.h has timersub |
| ... | |
| src/Compat.cc | |
| 20 | @@ -20,6 +20,10 @@ |
| 20 | #include <wchar.h> |
| 21 | } |
| 22 | |
| 23 | #ifndef HAVE_UNSETENV |
| 24 | #include <errno.h> |
| 25 | #endif // ! HAVE_UNSETENV |
| 26 | |
| 27 | using std::string; |
| 28 | using std::wstring; |
| 29 | |
| ... | |
| 101 | @@ -97,4 +101,20 @@ |
| 101 | |
| 102 | return (putenv(str)); |
| 103 | } |
| 100 | #endif // HAVE_SETENV |
| 105 | #endif // ! HAVE_SETENV |
| 106 | |
| 107 | #ifndef HAVE_UNSETENV |
| 108 | /** |
| 109 | * Compat unsetenv, removes variable from the environment. |
| 110 | */ |
| 111 | int |
| 112 | unsetenv(const char *name) { |
| 113 | const char *value = getenv(name); |
| 114 | if (value && strlen(value)) { |
| 115 | return setenv(name, "", 1); |
| 116 | } else { |
| 117 | errno = EINVAL; |
| 118 | return -1; |
| 119 | } |
| 120 | } |
| 121 | #endif // ! HAVE_UNSETENV |
| ... | |
| src/Compat.hh | |
| 30 | @@ -30,6 +30,14 @@ |
| 30 | int setenv(const char *name, const char *value, int overwrite); |
| 31 | #endif // HAVE_SETENV |
| 32 | |
| 33 | #ifdef HAVE_UNSETENV |
| 34 | extern "C" { |
| 35 | #include <stdlib.h> |
| 36 | } |
| 37 | #else // ! HAVE_UNSETENV |
| 38 | int unsetenv(const char *name); |
| 39 | #endif // HAVE_UNSETENV |
| 40 | |
| 41 | #ifndef HAVE_TIMERSUB |
| 42 | #define timersub(a, b, result) \ |
| 43 | do { \ |
| ... | |
| src/ActionHandler.cc | |
| 351 | @@ -351,8 +351,7 @@ |
| 351 | actionGotoClientID(it->getParamI(0)); |
| 352 | break; |
| 353 | case ACTION_EXEC: |
| 354 | if (it->getParamS().size()) |
| 355 | Util::forkExec(it->getParamS()); |
| 356 | actionExec(client, it->getParamS()); |
| 357 | break; |
| 358 | #ifdef MENUS |
| 359 | case ACTION_SHOW_MENU: |
| ... | |
| 532 | @@ -533,6 +532,18 @@ |
| 532 | return 0; |
| 533 | } |
| 534 | |
| 535 | /** |
| 536 | * Execute action, setting client environment before (if any). |
| 537 | */ |
| 538 | void |
| 539 | ActionHandler::actionExec(Client *client, const std::string &command) |
| 540 | { |
| 541 | if (command.size()) { |
| 542 | Client::setClientEnvironment(client); |
| 543 | Util::forkExec(command); |
| 544 | } |
| 545 | } |
| 546 | |
| 547 | //! @brief Searches for a client matching titles and makes it visible |
| 548 | void |
| 549 | ActionHandler::actionFindClient(const std::wstring &title) |
| ... | |
| src/ActionHandler.hh | |
| 43 | @@ -43,6 +43,7 @@ |
| 43 | private: |
| 44 | void handleStateAction(const Action &action, PWinObj *wo, Client *client, Frame *frame); |
| 45 | |
| 46 | void actionExec(Client *client, const std::string &command); |
| 47 | void actionFindClient(const std::wstring &title); |
| 48 | void actionGotoClientID(uint id); |
| 49 | void actionGotoWorkspace(uint workspace, bool warp); |
| ... | |
| src/ActionMenu.cc | |
| 309 | @@ -309,11 +309,11 @@ |
| 309 | PWinObj *wo_ref = getWORef(); |
| 310 | |
| 311 | // Export environment before to dynamic script. |
| 312 | Client *client = 0; |
| 313 | if (wo_ref && wo_ref->getType() == WO_CLIENT) { |
| 314 | Client *client = static_cast<Client*>(wo_ref); |
| 315 | setenv("CLIENT_PID", Util::to_string<long>(client->isRemote() ? -1 : client->getPid()).c_str(), 1); |
| 316 | setenv("CLIENT_WINDOW", Util::to_string<Window>(client->getWindow()).c_str(), 1); |
| 317 | client = static_cast<Client*>(wo_ref); |
| 318 | } |
| 319 | Client::setClientEnvironment(client); |
| 320 | |
| 321 | // Setup icon path before parsing. |
| 322 | ImageHandler::instance()->path_push_back(Config::instance()->getSystemIconPath()); |
| ... | |
| src/Client.cc | |
| 26 | @@ -26,6 +26,7 @@ |
| 26 | #endif // HAVE_SHAPE |
| 27 | } |
| 28 | |
| 29 | #include "Compat.hh" // setenv, unsetenv |
| 30 | #include "PWinObj.hh" |
| 31 | #include "PDecor.hh" // PDecor::TitleItem |
| 32 | #include "Client.hh" |
| ... | |
| 1776 | @@ -1775,3 +1776,18 @@ |
| 1776 | { |
| 1777 | AtomUtil::setLong(_window, Atoms::getAtom(PEKWM_FRAME_ACTIVE), act ? 1 : 0); |
| 1778 | } |
| 1779 | |
| 1780 | /** |
| 1781 | * Update the environment with CLIENT_PID and CLIENT_WINDOW. |
| 1782 | */ |
| 1783 | void |
| 1784 | Client::setClientEnvironment(Client *client) |
| 1785 | { |
| 1786 | if (client) { |
| 1787 | setenv("CLIENT_PID", Util::to_string<long>(client->isRemote() ? -1 : client->getPid()).c_str(), 1); |
| 1788 | setenv("CLIENT_WINDOW", Util::to_string<Window>(client->getWindow()).c_str(), 1); |
| 1789 | } else { |
| 1790 | unsetenv("CLIENT_PID"); |
| 1791 | unsetenv("CLIENT_WINDOW"); |
| 1792 | } |
| 1793 | } |
| ... | |
| src/Client.hh | |
| 262 | @@ -262,6 +262,8 @@ |
| 262 | bool getPekwmFrameActive(void); |
| 263 | void setPekwmFrameActive(bool active); |
| 264 | |
| 265 | static void setClientEnvironment(Client *client); |
| 266 | |
| 267 | private: |
| 268 | bool getAndUpdateWindowAttributes(void); |
| 269 | |
| ... | |