Adds 'ClientPatternTest' command
ClientPatterns might be tricky to get right. Instead of fiddling around in either the keys-file or the apps-file and restarting fluxbox to see if the changes had any effect / matched the right windows, 'ClientPatternTest' and the fluxbox-remote should make this easier: $> fluxbox-remote "clientpatterntest (title=.*vim*)" This causes fluxbox to store the list of matched windows in the _FLUXBOX_ACTION_RESULT property onto the rootwindow. This property might then be read by: $> xprop -root _FLUXBOX_ACTION_RESULT or $> fluxbox-remote result The format of the list is: win_id \t title_of_window \n win_id is '-1' when fluxbox wasn't able to parse the given ClientPattern. win_id is '0' when there are no windows matching the given ClientPattern.
This commit is contained in:
parent
716532dd47
commit
dc47491533
7 changed files with 177 additions and 53 deletions
|
@ -89,6 +89,7 @@ public:
|
||||||
* the column of the error is stored in m_matchlimit
|
* the column of the error is stored in m_matchlimit
|
||||||
*/
|
*/
|
||||||
int error() const { return m_terms.empty() ? 1 : 0; }
|
int error() const { return m_terms.empty() ? 1 : 0; }
|
||||||
|
int error_col() const { return m_matchlimit; }
|
||||||
|
|
||||||
static FbTk::FbString getProperty(WinProperty prop, const Focusable &client);
|
static FbTk::FbString getProperty(WinProperty prop, const Focusable &client);
|
||||||
|
|
||||||
|
|
|
@ -445,13 +445,12 @@ REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(bindkey, FbCommands::BindKeyCmd, void);
|
||||||
BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { }
|
BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { }
|
||||||
|
|
||||||
void BindKeyCmd::execute() {
|
void BindKeyCmd::execute() {
|
||||||
if (Fluxbox::instance()->keys() != 0) {
|
Keys* keys = Fluxbox::instance()->keys();
|
||||||
if (Fluxbox::instance()->keys()->addBinding(m_keybind)) {
|
if (keys && keys->addBinding(m_keybind)) {
|
||||||
ofstream ofile(Fluxbox::instance()->keys()->filename().c_str(), ios::app);
|
ofstream ofile(keys->filename().c_str(), ios::app);
|
||||||
if (!ofile)
|
if (!ofile)
|
||||||
return;
|
return;
|
||||||
ofile<<m_keybind<<endl;
|
ofile<<m_keybind<<endl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,4 +541,73 @@ void DeiconifyCmd::execute() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
REGISTER_COMMAND_WITH_ARGS(clientpatterntest, FbCommands::ClientPatternTestCmd, void);
|
||||||
|
|
||||||
|
void ClientPatternTestCmd::execute() {
|
||||||
|
|
||||||
|
std::vector< const FluxboxWindow* > matches;
|
||||||
|
std::string result;
|
||||||
|
std::string pat;
|
||||||
|
int opts;
|
||||||
|
ClientPattern* cp;
|
||||||
|
Display* dpy;
|
||||||
|
Atom atom_utf8;
|
||||||
|
Atom atom_fbcmd_result;
|
||||||
|
Fluxbox::ScreenList::const_iterator screen;
|
||||||
|
const Fluxbox::ScreenList screens(Fluxbox::instance()->screenList());
|
||||||
|
|
||||||
|
dpy = Fluxbox::instance()->display();
|
||||||
|
atom_utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
|
atom_fbcmd_result = XInternAtom(dpy, "_FLUXBOX_ACTION_RESULT", False);
|
||||||
|
|
||||||
|
FocusableList::parseArgs(m_args, opts, pat);
|
||||||
|
cp = new ClientPattern(pat.c_str());
|
||||||
|
|
||||||
|
if (!cp->error()) {
|
||||||
|
|
||||||
|
const FocusableList* windows;
|
||||||
|
FocusControl::Focusables::const_iterator wit;
|
||||||
|
FocusControl::Focusables::const_iterator wit_end;
|
||||||
|
|
||||||
|
for (screen = screens.begin(); screen != screens.end(); screen++) {
|
||||||
|
|
||||||
|
windows = FocusableList::getListFromOptions(**screen, opts|FocusableList::LIST_GROUPS);
|
||||||
|
wit = windows->clientList().begin();
|
||||||
|
wit_end = windows->clientList().end();
|
||||||
|
|
||||||
|
for ( ; wit != wit_end; wit++) {
|
||||||
|
if (typeid(**wit) == typeid(FluxboxWindow) && cp->match(**wit)) {
|
||||||
|
matches.push_back(static_cast<const FluxboxWindow*>(*wit));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matches.empty()) {
|
||||||
|
std::vector< const FluxboxWindow* >::const_iterator win;
|
||||||
|
for (win = matches.begin(); win != matches.end(); win++) {
|
||||||
|
result += "0x";
|
||||||
|
result += FbTk::StringUtil::number2HexString((*win)->clientWindow());
|
||||||
|
result += "\t";
|
||||||
|
result += (*win)->title().logical();
|
||||||
|
result += "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result += "0\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = "-1\t";
|
||||||
|
result += FbTk::StringUtil::number2String(cp->error_col());
|
||||||
|
result += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// write result to _FLUXBOX_ACTION_RESULT property
|
||||||
|
for (screen = screens.begin(); screen != screens.end(); screen++) {
|
||||||
|
(*screen)->rootWindow().changeProperty(atom_fbcmd_result, atom_utf8, 8,
|
||||||
|
PropModeReplace, (unsigned char*)result.c_str(), result.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end namespace FbCommands
|
} // end namespace FbCommands
|
||||||
|
|
|
@ -218,6 +218,16 @@ private:
|
||||||
Destination m_dest;
|
Destination m_dest;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// test client pattern
|
||||||
|
class ClientPatternTestCmd: public FbTk::Command<void> {
|
||||||
|
public:
|
||||||
|
ClientPatternTestCmd(const std::string& args) : m_args(args) { };
|
||||||
|
void execute();
|
||||||
|
private:
|
||||||
|
std::string m_args;
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace FbCommands
|
} // end namespace FbCommands
|
||||||
|
|
||||||
#endif // FBCOMMANDS_HH
|
#endif // FBCOMMANDS_HH
|
||||||
|
|
|
@ -145,10 +145,17 @@ int extractNumber(const std::string& in, unsigned long long& out) {
|
||||||
|
|
||||||
std::string number2String(long long num) {
|
std::string number2String(long long num) {
|
||||||
char s[128];
|
char s[128];
|
||||||
sprintf(s, "%lld", num);
|
snprintf(s, sizeof(s), "%lld", num);
|
||||||
return std::string(s);
|
return std::string(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string number2HexString(long long num) {
|
||||||
|
char s[17];
|
||||||
|
snprintf(s, sizeof(s), "%lx", num);
|
||||||
|
return std::string(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Tries to find a string in another and
|
Tries to find a string in another and
|
||||||
ignoring the case of the characters
|
ignoring the case of the characters
|
||||||
|
|
|
@ -44,6 +44,7 @@ int extractNumber(const std::string& in, unsigned long long& out);
|
||||||
|
|
||||||
/// creates a number to a string
|
/// creates a number to a string
|
||||||
std::string number2String(long long num);
|
std::string number2String(long long num);
|
||||||
|
std::string number2HexString(long long num);
|
||||||
|
|
||||||
/// Similar to `strstr' but this function ignores the case of both strings
|
/// Similar to `strstr' but this function ignores the case of both strings
|
||||||
const char *strcasestr(const char *str, const char *ptn);
|
const char *strcasestr(const char *str, const char *ptn);
|
||||||
|
|
|
@ -231,6 +231,22 @@ const TabPlacementString placement_strings[] = {
|
||||||
{ FbWinFrame::RIGHTTOP, "RightTop" }
|
{ FbWinFrame::RIGHTTOP, "RightTop" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Atom atom_fbcmd = 0;
|
||||||
|
Atom atom_wm_check = 0;
|
||||||
|
Atom atom_net_desktop = 0;
|
||||||
|
Atom atom_utf8_string = 0;
|
||||||
|
Atom atom_kde_systray = 0;
|
||||||
|
Atom atom_kwm1 = 0;
|
||||||
|
|
||||||
|
void initAtoms(Display* dpy) {
|
||||||
|
atom_wm_check = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
|
||||||
|
atom_net_desktop = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
|
||||||
|
atom_fbcmd = XInternAtom(dpy, "_FLUXBOX_ACTION", False);
|
||||||
|
atom_utf8_string = XInternAtom(dpy, "UTF8_STRING", False);
|
||||||
|
atom_kde_systray = XInternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
|
||||||
|
atom_kwm1 = XInternAtom(dpy, "KWM_DOCKWINDOW", False);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
@ -317,8 +333,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
||||||
m_geom_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
|
m_geom_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
|
||||||
m_pos_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
|
m_pos_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
|
||||||
m_tooltip_window(new TooltipWindow(m_root_window, *this, *m_focused_windowtheme)),
|
m_tooltip_window(new TooltipWindow(m_root_window, *this, *m_focused_windowtheme)),
|
||||||
m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent,
|
m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent, InputOnly),
|
||||||
InputOnly),
|
|
||||||
resource(rm, screenname, altscreenname),
|
resource(rm, screenname, altscreenname),
|
||||||
m_resource_manager(rm),
|
m_resource_manager(rm),
|
||||||
m_name(screenname),
|
m_name(screenname),
|
||||||
|
@ -331,8 +346,11 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
||||||
m_shutdown(false) {
|
m_shutdown(false) {
|
||||||
|
|
||||||
|
|
||||||
Display *disp = m_root_window.display();
|
|
||||||
Fluxbox *fluxbox = Fluxbox::instance();
|
Fluxbox *fluxbox = Fluxbox::instance();
|
||||||
|
Display *disp = fluxbox->display();
|
||||||
|
|
||||||
|
initAtoms(disp);
|
||||||
|
|
||||||
|
|
||||||
// TODO fluxgen: check if this is the right place (it was not -lis)
|
// TODO fluxgen: check if this is the right place (it was not -lis)
|
||||||
//
|
//
|
||||||
|
@ -349,7 +367,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
||||||
SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
|
SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
|
||||||
ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask);
|
ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask);
|
||||||
|
|
||||||
FbTk::App::instance()->sync(false);
|
fluxbox->sync(false);
|
||||||
|
|
||||||
XSetErrorHandler((XErrorHandler) old);
|
XSetErrorHandler((XErrorHandler) old);
|
||||||
|
|
||||||
|
@ -370,12 +388,11 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
||||||
#endif // HAVE_GETPID
|
#endif // HAVE_GETPID
|
||||||
|
|
||||||
// check if we're the first EWMH compliant window manager on this screen
|
// check if we're the first EWMH compliant window manager on this screen
|
||||||
Atom wm_check = XInternAtom(disp, "_NET_SUPPORTING_WM_CHECK", False);
|
|
||||||
Atom xa_ret_type;
|
Atom xa_ret_type;
|
||||||
int ret_format;
|
int ret_format;
|
||||||
unsigned long ret_nitems, ret_bytes_after;
|
unsigned long ret_nitems, ret_bytes_after;
|
||||||
unsigned char *ret_prop;
|
unsigned char *ret_prop;
|
||||||
if (rootWindow().property(wm_check, 0l, 1l,
|
if (rootWindow().property(atom_wm_check, 0l, 1l,
|
||||||
False, XA_WINDOW, &xa_ret_type, &ret_format, &ret_nitems,
|
False, XA_WINDOW, &xa_ret_type, &ret_format, &ret_nitems,
|
||||||
&ret_bytes_after, &ret_prop) ) {
|
&ret_bytes_after, &ret_prop) ) {
|
||||||
m_restart = (ret_prop != NULL);
|
m_restart = (ret_prop != NULL);
|
||||||
|
@ -415,7 +432,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
||||||
|
|
||||||
FbTk::EventManager *evm = FbTk::EventManager::instance();
|
FbTk::EventManager *evm = FbTk::EventManager::instance();
|
||||||
evm->add(*this, rootWindow());
|
evm->add(*this, rootWindow());
|
||||||
Keys *keys = Fluxbox::instance()->keys();
|
Keys *keys = fluxbox->keys();
|
||||||
if (keys)
|
if (keys)
|
||||||
keys->registerWindow(rootWindow().window(), *this,
|
keys->registerWindow(rootWindow().window(), *this,
|
||||||
Keys::GLOBAL|Keys::ON_DESKTOP);
|
Keys::GLOBAL|Keys::ON_DESKTOP);
|
||||||
|
@ -476,9 +493,8 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
||||||
// check which desktop we should start on
|
// check which desktop we should start on
|
||||||
unsigned int first_desktop = 0;
|
unsigned int first_desktop = 0;
|
||||||
if (m_restart) {
|
if (m_restart) {
|
||||||
Atom net_desktop = XInternAtom(disp, "_NET_CURRENT_DESKTOP", False);
|
|
||||||
bool exists;
|
bool exists;
|
||||||
unsigned int ret=static_cast<unsigned int>(rootWindow().cardinalProperty(net_desktop, &exists));
|
unsigned int ret=static_cast<unsigned int>(rootWindow().cardinalProperty(atom_net_desktop, &exists));
|
||||||
if (exists) {
|
if (exists) {
|
||||||
if (ret < static_cast<unsigned int>(nr_ws))
|
if (ret < static_cast<unsigned int>(nr_ws))
|
||||||
first_desktop = ret;
|
first_desktop = ret;
|
||||||
|
@ -764,29 +780,29 @@ void BScreen::focusedWinFrameThemeReconfigured() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BScreen::propertyNotify(Atom atom) {
|
void BScreen::propertyNotify(Atom atom) {
|
||||||
static Atom fbcmd_atom = XInternAtom(FbTk::App::instance()->display(),
|
|
||||||
"_FLUXBOX_ACTION", False);
|
if (allowRemoteActions() && atom == atom_fbcmd) {
|
||||||
if (allowRemoteActions() && atom == fbcmd_atom) {
|
|
||||||
Atom xa_ret_type;
|
Atom xa_ret_type;
|
||||||
int ret_format;
|
int ret_format;
|
||||||
unsigned long ret_nitems, ret_bytes_after;
|
unsigned long ret_nitems, ret_bytes_after;
|
||||||
char *str;
|
char *str;
|
||||||
if (rootWindow().property(fbcmd_atom, 0l, 64l,
|
if (rootWindow().property(atom_fbcmd, 0l, 64l,
|
||||||
True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
|
True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
|
||||||
&ret_bytes_after, (unsigned char **)&str) && str) {
|
&ret_bytes_after, (unsigned char **)&str) && str) {
|
||||||
|
|
||||||
if (ret_bytes_after) {
|
if (ret_bytes_after) {
|
||||||
XFree(str);
|
XFree(str);
|
||||||
long len = 64 + (ret_bytes_after + 3)/4;
|
long len = 64 + (ret_bytes_after + 3)/4;
|
||||||
rootWindow().property(fbcmd_atom, 0l, len,
|
rootWindow().property(atom_fbcmd, 0l, len,
|
||||||
True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
|
True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
|
||||||
&ret_bytes_after, (unsigned char **)&str);
|
&ret_bytes_after, (unsigned char **)&str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::auto_ptr<FbTk::Command<void> > cmd(0);
|
static std::auto_ptr<FbTk::Command<void> > cmd(0);
|
||||||
cmd.reset(FbTk::CommandParser<void>::instance().parse(str, false));
|
cmd.reset(FbTk::CommandParser<void>::instance().parse(str, false));
|
||||||
if (cmd.get())
|
if (cmd.get()) {
|
||||||
cmd->execute();
|
cmd->execute();
|
||||||
|
}
|
||||||
XFree(str);
|
XFree(str);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -852,9 +868,8 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FbMenu *BScreen::createMenu(const string &label) {
|
FbMenu *BScreen::createMenu(const string &label) {
|
||||||
FbMenu *menu = new FbMenu(menuTheme(),
|
FbTk::Layer* layer = layerManager().getLayer(ResourceLayer::MENU);
|
||||||
imageControl(),
|
FbMenu *menu = new FbMenu(menuTheme(), imageControl(), *layer);
|
||||||
*layerManager().getLayer(ResourceLayer::MENU));
|
|
||||||
if (!label.empty())
|
if (!label.empty())
|
||||||
menu->setLabel(label);
|
menu->setLabel(label);
|
||||||
|
|
||||||
|
@ -862,9 +877,8 @@ FbMenu *BScreen::createMenu(const string &label) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FbMenu *BScreen::createToggleMenu(const string &label) {
|
FbMenu *BScreen::createToggleMenu(const string &label) {
|
||||||
FbMenu *menu = new ToggleMenu(menuTheme(),
|
FbTk::Layer* layer = layerManager().getLayer(ResourceLayer::MENU);
|
||||||
imageControl(),
|
FbMenu *menu = new ToggleMenu(menuTheme(), imageControl(), *layer);
|
||||||
*layerManager().getLayer(ResourceLayer::MENU));
|
|
||||||
if (!label.empty())
|
if (!label.empty())
|
||||||
menu->setLabel(label);
|
menu->setLabel(label);
|
||||||
|
|
||||||
|
@ -1177,9 +1191,7 @@ bool BScreen::isKdeDockapp(Window client) const {
|
||||||
unsigned long *data = 0, uljunk;
|
unsigned long *data = 0, uljunk;
|
||||||
Display *disp = FbTk::App::instance()->display();
|
Display *disp = FbTk::App::instance()->display();
|
||||||
// Check if KDE v2.x dock applet
|
// Check if KDE v2.x dock applet
|
||||||
if (XGetWindowProperty(disp, client,
|
if (XGetWindowProperty(disp, client, atom_kde_systray,
|
||||||
XInternAtom(FbTk::App::instance()->display(),
|
|
||||||
"_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False),
|
|
||||||
0l, 1l, False,
|
0l, 1l, False,
|
||||||
XA_WINDOW, &ajunk, &ijunk, &uljunk,
|
XA_WINDOW, &ajunk, &ijunk, &uljunk,
|
||||||
&uljunk, (unsigned char **) &data) == Success) {
|
&uljunk, (unsigned char **) &data) == Success) {
|
||||||
|
@ -1192,11 +1204,9 @@ bool BScreen::isKdeDockapp(Window client) const {
|
||||||
|
|
||||||
// Check if KDE v1.x dock applet
|
// Check if KDE v1.x dock applet
|
||||||
if (!iskdedockapp) {
|
if (!iskdedockapp) {
|
||||||
Atom kwm1 = XInternAtom(FbTk::App::instance()->display(),
|
|
||||||
"KWM_DOCKWINDOW", False);
|
|
||||||
if (XGetWindowProperty(disp, client,
|
if (XGetWindowProperty(disp, client,
|
||||||
kwm1, 0l, 1l, False,
|
atom_kwm1, 0l, 1l, False,
|
||||||
kwm1, &ajunk, &ijunk, &uljunk,
|
atom_kwm1, &ajunk, &ijunk, &uljunk,
|
||||||
&uljunk, (unsigned char **) &data) == Success && data) {
|
&uljunk, (unsigned char **) &data) == Success && data) {
|
||||||
iskdedockapp = (data && data[0] != 0);
|
iskdedockapp = (data && data[0] != 0);
|
||||||
XFree((void *) data);
|
XFree((void *) data);
|
||||||
|
|
|
@ -21,50 +21,77 @@
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
bool g_gotError;
|
|
||||||
|
bool g_gotError = false;
|
||||||
static int HandleIPCError(Display *disp, XErrorEvent*ptr)
|
static int HandleIPCError(Display *disp, XErrorEvent*ptr)
|
||||||
{
|
{
|
||||||
// ptr->error_code contains the actual error flags
|
// ptr->error_code contains the actual error flags
|
||||||
g_gotError=true;
|
g_gotError = true;
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef int (*xerror_cb_t)(Display*,XErrorEvent*);
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
Display* disp;
|
||||||
|
Window root;
|
||||||
|
Atom atom_utf8;
|
||||||
|
Atom atom_fbcmd;
|
||||||
|
Atom atom_result;
|
||||||
|
xerror_cb_t error_cb;
|
||||||
|
char* cmd;
|
||||||
|
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
printf("fluxbox-remote <fluxbox-command>\n");
|
printf("fluxbox-remote <fluxbox-command>\n");
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Display *disp = XOpenDisplay(NULL);
|
disp = XOpenDisplay(NULL);
|
||||||
if (!disp) {
|
if (!disp) {
|
||||||
perror("error, can't open display.");
|
perror("error, can't open display.");
|
||||||
return EXIT_FAILURE;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Atom fbcmd_atom = XInternAtom(disp, "_FLUXBOX_ACTION", False);
|
cmd = argv[1];
|
||||||
Window root = DefaultRootWindow(disp);
|
atom_utf8 = XInternAtom(disp, "UTF8_STRING", False);
|
||||||
|
atom_fbcmd = XInternAtom(disp, "_FLUXBOX_ACTION", False);
|
||||||
|
atom_result = XInternAtom(disp, "_FLUXBOX_ACTION_RESULT", False);
|
||||||
|
root = DefaultRootWindow(disp);
|
||||||
|
|
||||||
char *str = argv[1];
|
// assign the custom handler, clear the flag, sync the data,
|
||||||
|
// then check it for success/failure
|
||||||
|
error_cb = XSetErrorHandler(HandleIPCError);
|
||||||
|
|
||||||
typedef int (*x_error_handler_t)(Display*,XErrorEvent*);
|
|
||||||
|
|
||||||
// assign the custom handler, clear the flag, sync the data, then check it for success/failure
|
if (strcmp(cmd, "result") == 0) {
|
||||||
x_error_handler_t handler = XSetErrorHandler( HandleIPCError );
|
XTextProperty text_prop;
|
||||||
g_gotError=false;
|
if (XGetTextProperty(disp, root, &text_prop, atom_result) != 0
|
||||||
XChangeProperty(disp, root, fbcmd_atom,
|
&& text_prop.value > 0
|
||||||
|
&& text_prop.nitems > 0) {
|
||||||
|
|
||||||
|
printf("%s", text_prop.value);
|
||||||
|
XFree(text_prop.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
XChangeProperty(disp, root, atom_fbcmd,
|
||||||
XA_STRING, 8, PropModeReplace,
|
XA_STRING, 8, PropModeReplace,
|
||||||
(unsigned char *) str, strlen(str));
|
(unsigned char *)cmd, strlen(cmd));
|
||||||
XSync(disp,False);
|
XSync(disp, false);
|
||||||
int ret=(g_gotError?EXIT_FAILURE:EXIT_SUCCESS);
|
}
|
||||||
XSetErrorHandler(handler);
|
|
||||||
|
|
||||||
|
rc = (g_gotError ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
|
|
||||||
|
XSetErrorHandler(error_cb);
|
||||||
XCloseDisplay(disp);
|
XCloseDisplay(disp);
|
||||||
|
|
||||||
return ret;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue