diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2013-01-31 08:13:45 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2013-01-31 08:14:06 (GMT) |
commit | dc47491533e0ca7cf5a5386a10e68fbaf873e9db (patch) | |
tree | 4ee0c68722207189912a106d3f77e9cab52e65a8 | |
parent | 716532dd47d718cb548da5f65b53a8b744ce235f (diff) | |
download | fluxbox_pavel-dc47491533e0ca7cf5a5386a10e68fbaf873e9db.zip fluxbox_pavel-dc47491533e0ca7cf5a5386a10e68fbaf873e9db.tar.bz2 |
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.
-rw-r--r-- | src/ClientPattern.hh | 1 | ||||
-rw-r--r-- | src/FbCommands.cc | 82 | ||||
-rw-r--r-- | src/FbCommands.hh | 10 | ||||
-rw-r--r-- | src/FbTk/StringUtil.cc | 9 | ||||
-rw-r--r-- | src/FbTk/StringUtil.hh | 1 | ||||
-rw-r--r-- | src/Screen.cc | 66 | ||||
-rw-r--r-- | util/fluxbox-remote.cc | 61 |
7 files changed, 177 insertions, 53 deletions
diff --git a/src/ClientPattern.hh b/src/ClientPattern.hh index a5b7206..358977a 100644 --- a/src/ClientPattern.hh +++ b/src/ClientPattern.hh | |||
@@ -89,6 +89,7 @@ public: | |||
89 | * the column of the error is stored in m_matchlimit | 89 | * the column of the error is stored in m_matchlimit |
90 | */ | 90 | */ |
91 | int error() const { return m_terms.empty() ? 1 : 0; } | 91 | int error() const { return m_terms.empty() ? 1 : 0; } |
92 | int error_col() const { return m_matchlimit; } | ||
92 | 93 | ||
93 | static FbTk::FbString getProperty(WinProperty prop, const Focusable &client); | 94 | static FbTk::FbString getProperty(WinProperty prop, const Focusable &client); |
94 | 95 | ||
diff --git a/src/FbCommands.cc b/src/FbCommands.cc index b0289b8..eb7fbfd 100644 --- a/src/FbCommands.cc +++ b/src/FbCommands.cc | |||
@@ -445,13 +445,12 @@ REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(bindkey, FbCommands::BindKeyCmd, void); | |||
445 | BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { } | 445 | BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { } |
446 | 446 | ||
447 | void BindKeyCmd::execute() { | 447 | void BindKeyCmd::execute() { |
448 | if (Fluxbox::instance()->keys() != 0) { | 448 | Keys* keys = Fluxbox::instance()->keys(); |
449 | if (Fluxbox::instance()->keys()->addBinding(m_keybind)) { | 449 | if (keys && keys->addBinding(m_keybind)) { |
450 | ofstream ofile(Fluxbox::instance()->keys()->filename().c_str(), ios::app); | 450 | ofstream ofile(keys->filename().c_str(), ios::app); |
451 | if (!ofile) | 451 | if (!ofile) |
452 | return; | 452 | return; |
453 | ofile<<m_keybind<<endl; | 453 | ofile<<m_keybind<<endl; |
454 | } | ||
455 | } | 454 | } |
456 | } | 455 | } |
457 | 456 | ||
@@ -542,4 +541,73 @@ void DeiconifyCmd::execute() { | |||
542 | }; | 541 | }; |
543 | } | 542 | } |
544 | 543 | ||
544 | |||
545 | REGISTER_COMMAND_WITH_ARGS(clientpatterntest, FbCommands::ClientPatternTestCmd, void); | ||
546 | |||
547 | void ClientPatternTestCmd::execute() { | ||
548 | |||
549 | std::vector< const FluxboxWindow* > matches; | ||
550 | std::string result; | ||
551 | std::string pat; | ||
552 | int opts; | ||
553 | ClientPattern* cp; | ||
554 | Display* dpy; | ||
555 | Atom atom_utf8; | ||
556 | Atom atom_fbcmd_result; | ||
557 | Fluxbox::ScreenList::const_iterator screen; | ||
558 | const Fluxbox::ScreenList screens(Fluxbox::instance()->screenList()); | ||
559 | |||
560 | dpy = Fluxbox::instance()->display(); | ||
561 | atom_utf8 = XInternAtom(dpy, "UTF8_STRING", False); | ||
562 | atom_fbcmd_result = XInternAtom(dpy, "_FLUXBOX_ACTION_RESULT", False); | ||
563 | |||
564 | FocusableList::parseArgs(m_args, opts, pat); | ||
565 | cp = new ClientPattern(pat.c_str()); | ||
566 | |||
567 | if (!cp->error()) { | ||
568 | |||
569 | const FocusableList* windows; | ||
570 | FocusControl::Focusables::const_iterator wit; | ||
571 | FocusControl::Focusables::const_iterator wit_end; | ||
572 | |||
573 | for (screen = screens.begin(); screen != screens.end(); screen++) { | ||
574 | |||
575 | windows = FocusableList::getListFromOptions(**screen, opts|FocusableList::LIST_GROUPS); | ||
576 | wit = windows->clientList().begin(); | ||
577 | wit_end = windows->clientList().end(); | ||
578 | |||
579 | for ( ; wit != wit_end; wit++) { | ||
580 | if (typeid(**wit) == typeid(FluxboxWindow) && cp->match(**wit)) { | ||
581 | matches.push_back(static_cast<const FluxboxWindow*>(*wit)); | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | |||
586 | if (!matches.empty()) { | ||
587 | std::vector< const FluxboxWindow* >::const_iterator win; | ||
588 | for (win = matches.begin(); win != matches.end(); win++) { | ||
589 | result += "0x"; | ||
590 | result += FbTk::StringUtil::number2HexString((*win)->clientWindow()); | ||
591 | result += "\t"; | ||
592 | result += (*win)->title().logical(); | ||
593 | result += "\n"; | ||
594 | } | ||
595 | } else { | ||
596 | result += "0\n"; | ||
597 | } | ||
598 | } else { | ||
599 | result = "-1\t"; | ||
600 | result += FbTk::StringUtil::number2String(cp->error_col()); | ||
601 | result += "\n"; | ||
602 | } | ||
603 | |||
604 | |||
605 | // write result to _FLUXBOX_ACTION_RESULT property | ||
606 | for (screen = screens.begin(); screen != screens.end(); screen++) { | ||
607 | (*screen)->rootWindow().changeProperty(atom_fbcmd_result, atom_utf8, 8, | ||
608 | PropModeReplace, (unsigned char*)result.c_str(), result.size()); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | |||
545 | } // end namespace FbCommands | 613 | } // end namespace FbCommands |
diff --git a/src/FbCommands.hh b/src/FbCommands.hh index b6b1f7f..d9639ad 100644 --- a/src/FbCommands.hh +++ b/src/FbCommands.hh | |||
@@ -218,6 +218,16 @@ private: | |||
218 | Destination m_dest; | 218 | Destination m_dest; |
219 | }; | 219 | }; |
220 | 220 | ||
221 | |||
222 | /// test client pattern | ||
223 | class ClientPatternTestCmd: public FbTk::Command<void> { | ||
224 | public: | ||
225 | ClientPatternTestCmd(const std::string& args) : m_args(args) { }; | ||
226 | void execute(); | ||
227 | private: | ||
228 | std::string m_args; | ||
229 | }; | ||
230 | |||
221 | } // end namespace FbCommands | 231 | } // end namespace FbCommands |
222 | 232 | ||
223 | #endif // FBCOMMANDS_HH | 233 | #endif // FBCOMMANDS_HH |
diff --git a/src/FbTk/StringUtil.cc b/src/FbTk/StringUtil.cc index 0dcd989..fa809be 100644 --- a/src/FbTk/StringUtil.cc +++ b/src/FbTk/StringUtil.cc | |||
@@ -145,10 +145,17 @@ int extractNumber(const std::string& in, unsigned long long& out) { | |||
145 | 145 | ||
146 | std::string number2String(long long num) { | 146 | std::string number2String(long long num) { |
147 | char s[128]; | 147 | char s[128]; |
148 | sprintf(s, "%lld", num); | 148 | snprintf(s, sizeof(s), "%lld", num); |
149 | return std::string(s); | 149 | return std::string(s); |
150 | } | 150 | } |
151 | 151 | ||
152 | std::string number2HexString(long long num) { | ||
153 | char s[17]; | ||
154 | snprintf(s, sizeof(s), "%lx", num); | ||
155 | return std::string(s); | ||
156 | } | ||
157 | |||
158 | |||
152 | /** | 159 | /** |
153 | Tries to find a string in another and | 160 | Tries to find a string in another and |
154 | ignoring the case of the characters | 161 | ignoring the case of the characters |
diff --git a/src/FbTk/StringUtil.hh b/src/FbTk/StringUtil.hh index 538828b..930e0b5 100644 --- a/src/FbTk/StringUtil.hh +++ b/src/FbTk/StringUtil.hh | |||
@@ -44,6 +44,7 @@ int extractNumber(const std::string& in, unsigned long long& out); | |||
44 | 44 | ||
45 | /// creates a number to a string | 45 | /// creates a number to a string |
46 | std::string number2String(long long num); | 46 | std::string number2String(long long num); |
47 | std::string number2HexString(long long num); | ||
47 | 48 | ||
48 | /// Similar to `strstr' but this function ignores the case of both strings | 49 | /// Similar to `strstr' but this function ignores the case of both strings |
49 | const char *strcasestr(const char *str, const char *ptn); | 50 | const char *strcasestr(const char *str, const char *ptn); |
diff --git a/src/Screen.cc b/src/Screen.cc index 637bd82..725d4b5 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -231,6 +231,22 @@ const TabPlacementString placement_strings[] = { | |||
231 | { FbWinFrame::RIGHTTOP, "RightTop" } | 231 | { FbWinFrame::RIGHTTOP, "RightTop" } |
232 | }; | 232 | }; |
233 | 233 | ||
234 | Atom atom_fbcmd = 0; | ||
235 | Atom atom_wm_check = 0; | ||
236 | Atom atom_net_desktop = 0; | ||
237 | Atom atom_utf8_string = 0; | ||
238 | Atom atom_kde_systray = 0; | ||
239 | Atom atom_kwm1 = 0; | ||
240 | |||
241 | void initAtoms(Display* dpy) { | ||
242 | atom_wm_check = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); | ||
243 | atom_net_desktop = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False); | ||
244 | atom_fbcmd = XInternAtom(dpy, "_FLUXBOX_ACTION", False); | ||
245 | atom_utf8_string = XInternAtom(dpy, "UTF8_STRING", False); | ||
246 | atom_kde_systray = XInternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); | ||
247 | atom_kwm1 = XInternAtom(dpy, "KWM_DOCKWINDOW", False); | ||
248 | } | ||
249 | |||
234 | 250 | ||
235 | } // end anonymous namespace | 251 | } // end anonymous namespace |
236 | 252 | ||
@@ -317,8 +333,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
317 | m_geom_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)), | 333 | m_geom_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)), |
318 | m_pos_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)), | 334 | m_pos_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)), |
319 | m_tooltip_window(new TooltipWindow(m_root_window, *this, *m_focused_windowtheme)), | 335 | m_tooltip_window(new TooltipWindow(m_root_window, *this, *m_focused_windowtheme)), |
320 | m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent, | 336 | m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent, InputOnly), |
321 | InputOnly), | ||
322 | resource(rm, screenname, altscreenname), | 337 | resource(rm, screenname, altscreenname), |
323 | m_resource_manager(rm), | 338 | m_resource_manager(rm), |
324 | m_name(screenname), | 339 | m_name(screenname), |
@@ -331,8 +346,11 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
331 | m_shutdown(false) { | 346 | m_shutdown(false) { |
332 | 347 | ||
333 | 348 | ||
334 | Display *disp = m_root_window.display(); | ||
335 | Fluxbox *fluxbox = Fluxbox::instance(); | 349 | Fluxbox *fluxbox = Fluxbox::instance(); |
350 | Display *disp = fluxbox->display(); | ||
351 | |||
352 | initAtoms(disp); | ||
353 | |||
336 | 354 | ||
337 | // TODO fluxgen: check if this is the right place (it was not -lis) | 355 | // TODO fluxgen: check if this is the right place (it was not -lis) |
338 | // | 356 | // |
@@ -349,7 +367,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
349 | SubstructureRedirectMask | KeyPressMask | KeyReleaseMask | | 367 | SubstructureRedirectMask | KeyPressMask | KeyReleaseMask | |
350 | ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask); | 368 | ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask); |
351 | 369 | ||
352 | FbTk::App::instance()->sync(false); | 370 | fluxbox->sync(false); |
353 | 371 | ||
354 | XSetErrorHandler((XErrorHandler) old); | 372 | XSetErrorHandler((XErrorHandler) old); |
355 | 373 | ||
@@ -370,12 +388,11 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
370 | #endif // HAVE_GETPID | 388 | #endif // HAVE_GETPID |
371 | 389 | ||
372 | // check if we're the first EWMH compliant window manager on this screen | 390 | // check if we're the first EWMH compliant window manager on this screen |
373 | Atom wm_check = XInternAtom(disp, "_NET_SUPPORTING_WM_CHECK", False); | ||
374 | Atom xa_ret_type; | 391 | Atom xa_ret_type; |
375 | int ret_format; | 392 | int ret_format; |
376 | unsigned long ret_nitems, ret_bytes_after; | 393 | unsigned long ret_nitems, ret_bytes_after; |
377 | unsigned char *ret_prop; | 394 | unsigned char *ret_prop; |
378 | if (rootWindow().property(wm_check, 0l, 1l, | 395 | if (rootWindow().property(atom_wm_check, 0l, 1l, |
379 | False, XA_WINDOW, &xa_ret_type, &ret_format, &ret_nitems, | 396 | False, XA_WINDOW, &xa_ret_type, &ret_format, &ret_nitems, |
380 | &ret_bytes_after, &ret_prop) ) { | 397 | &ret_bytes_after, &ret_prop) ) { |
381 | m_restart = (ret_prop != NULL); | 398 | m_restart = (ret_prop != NULL); |
@@ -415,7 +432,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
415 | 432 | ||
416 | FbTk::EventManager *evm = FbTk::EventManager::instance(); | 433 | FbTk::EventManager *evm = FbTk::EventManager::instance(); |
417 | evm->add(*this, rootWindow()); | 434 | evm->add(*this, rootWindow()); |
418 | Keys *keys = Fluxbox::instance()->keys(); | 435 | Keys *keys = fluxbox->keys(); |
419 | if (keys) | 436 | if (keys) |
420 | keys->registerWindow(rootWindow().window(), *this, | 437 | keys->registerWindow(rootWindow().window(), *this, |
421 | Keys::GLOBAL|Keys::ON_DESKTOP); | 438 | Keys::GLOBAL|Keys::ON_DESKTOP); |
@@ -476,9 +493,8 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
476 | // check which desktop we should start on | 493 | // check which desktop we should start on |
477 | unsigned int first_desktop = 0; | 494 | unsigned int first_desktop = 0; |
478 | if (m_restart) { | 495 | if (m_restart) { |
479 | Atom net_desktop = XInternAtom(disp, "_NET_CURRENT_DESKTOP", False); | ||
480 | bool exists; | 496 | bool exists; |
481 | unsigned int ret=static_cast<unsigned int>(rootWindow().cardinalProperty(net_desktop, &exists)); | 497 | unsigned int ret=static_cast<unsigned int>(rootWindow().cardinalProperty(atom_net_desktop, &exists)); |
482 | if (exists) { | 498 | if (exists) { |
483 | if (ret < static_cast<unsigned int>(nr_ws)) | 499 | if (ret < static_cast<unsigned int>(nr_ws)) |
484 | first_desktop = ret; | 500 | first_desktop = ret; |
@@ -764,29 +780,29 @@ void BScreen::focusedWinFrameThemeReconfigured() { | |||
764 | } | 780 | } |
765 | 781 | ||
766 | void BScreen::propertyNotify(Atom atom) { | 782 | void BScreen::propertyNotify(Atom atom) { |
767 | static Atom fbcmd_atom = XInternAtom(FbTk::App::instance()->display(), | 783 | |
768 | "_FLUXBOX_ACTION", False); | 784 | if (allowRemoteActions() && atom == atom_fbcmd) { |
769 | if (allowRemoteActions() && atom == fbcmd_atom) { | ||
770 | Atom xa_ret_type; | 785 | Atom xa_ret_type; |
771 | int ret_format; | 786 | int ret_format; |
772 | unsigned long ret_nitems, ret_bytes_after; | 787 | unsigned long ret_nitems, ret_bytes_after; |
773 | char *str; | 788 | char *str; |
774 | if (rootWindow().property(fbcmd_atom, 0l, 64l, | 789 | if (rootWindow().property(atom_fbcmd, 0l, 64l, |
775 | True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems, | 790 | True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems, |
776 | &ret_bytes_after, (unsigned char **)&str) && str) { | 791 | &ret_bytes_after, (unsigned char **)&str) && str) { |
777 | 792 | ||
778 | if (ret_bytes_after) { | 793 | if (ret_bytes_after) { |
779 | XFree(str); | 794 | XFree(str); |
780 | long len = 64 + (ret_bytes_after + 3)/4; | 795 | long len = 64 + (ret_bytes_after + 3)/4; |
781 | rootWindow().property(fbcmd_atom, 0l, len, | 796 | rootWindow().property(atom_fbcmd, 0l, len, |
782 | True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems, | 797 | True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems, |
783 | &ret_bytes_after, (unsigned char **)&str); | 798 | &ret_bytes_after, (unsigned char **)&str); |
784 | } | 799 | } |
785 | 800 | ||
786 | static std::auto_ptr<FbTk::Command<void> > cmd(0); | 801 | static std::auto_ptr<FbTk::Command<void> > cmd(0); |
787 | cmd.reset(FbTk::CommandParser<void>::instance().parse(str, false)); | 802 | cmd.reset(FbTk::CommandParser<void>::instance().parse(str, false)); |
788 | if (cmd.get()) | 803 | if (cmd.get()) { |
789 | cmd->execute(); | 804 | cmd->execute(); |
805 | } | ||
790 | XFree(str); | 806 | XFree(str); |
791 | 807 | ||
792 | } | 808 | } |
@@ -852,9 +868,8 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { | |||
852 | } | 868 | } |
853 | 869 | ||
854 | FbMenu *BScreen::createMenu(const string &label) { | 870 | FbMenu *BScreen::createMenu(const string &label) { |
855 | FbMenu *menu = new FbMenu(menuTheme(), | 871 | FbTk::Layer* layer = layerManager().getLayer(ResourceLayer::MENU); |
856 | imageControl(), | 872 | FbMenu *menu = new FbMenu(menuTheme(), imageControl(), *layer); |
857 | *layerManager().getLayer(ResourceLayer::MENU)); | ||
858 | if (!label.empty()) | 873 | if (!label.empty()) |
859 | menu->setLabel(label); | 874 | menu->setLabel(label); |
860 | 875 | ||
@@ -862,9 +877,8 @@ FbMenu *BScreen::createMenu(const string &label) { | |||
862 | } | 877 | } |
863 | 878 | ||
864 | FbMenu *BScreen::createToggleMenu(const string &label) { | 879 | FbMenu *BScreen::createToggleMenu(const string &label) { |
865 | FbMenu *menu = new ToggleMenu(menuTheme(), | 880 | FbTk::Layer* layer = layerManager().getLayer(ResourceLayer::MENU); |
866 | imageControl(), | 881 | FbMenu *menu = new ToggleMenu(menuTheme(), imageControl(), *layer); |
867 | *layerManager().getLayer(ResourceLayer::MENU)); | ||
868 | if (!label.empty()) | 882 | if (!label.empty()) |
869 | menu->setLabel(label); | 883 | menu->setLabel(label); |
870 | 884 | ||
@@ -1177,9 +1191,7 @@ bool BScreen::isKdeDockapp(Window client) const { | |||
1177 | unsigned long *data = 0, uljunk; | 1191 | unsigned long *data = 0, uljunk; |
1178 | Display *disp = FbTk::App::instance()->display(); | 1192 | Display *disp = FbTk::App::instance()->display(); |
1179 | // Check if KDE v2.x dock applet | 1193 | // Check if KDE v2.x dock applet |
1180 | if (XGetWindowProperty(disp, client, | 1194 | if (XGetWindowProperty(disp, client, atom_kde_systray, |
1181 | XInternAtom(FbTk::App::instance()->display(), | ||
1182 | "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False), | ||
1183 | 0l, 1l, False, | 1195 | 0l, 1l, False, |
1184 | XA_WINDOW, &ajunk, &ijunk, &uljunk, | 1196 | XA_WINDOW, &ajunk, &ijunk, &uljunk, |
1185 | &uljunk, (unsigned char **) &data) == Success) { | 1197 | &uljunk, (unsigned char **) &data) == Success) { |
@@ -1192,11 +1204,9 @@ bool BScreen::isKdeDockapp(Window client) const { | |||
1192 | 1204 | ||
1193 | // Check if KDE v1.x dock applet | 1205 | // Check if KDE v1.x dock applet |
1194 | if (!iskdedockapp) { | 1206 | if (!iskdedockapp) { |
1195 | Atom kwm1 = XInternAtom(FbTk::App::instance()->display(), | ||
1196 | "KWM_DOCKWINDOW", False); | ||
1197 | if (XGetWindowProperty(disp, client, | 1207 | if (XGetWindowProperty(disp, client, |
1198 | kwm1, 0l, 1l, False, | 1208 | atom_kwm1, 0l, 1l, False, |
1199 | kwm1, &ajunk, &ijunk, &uljunk, | 1209 | atom_kwm1, &ajunk, &ijunk, &uljunk, |
1200 | &uljunk, (unsigned char **) &data) == Success && data) { | 1210 | &uljunk, (unsigned char **) &data) == Success && data) { |
1201 | iskdedockapp = (data && data[0] != 0); | 1211 | iskdedockapp = (data && data[0] != 0); |
1202 | XFree((void *) data); | 1212 | XFree((void *) data); |
diff --git a/util/fluxbox-remote.cc b/util/fluxbox-remote.cc index 5c66583..340ac5b 100644 --- a/util/fluxbox-remote.cc +++ b/util/fluxbox-remote.cc | |||
@@ -21,50 +21,77 @@ | |||
21 | 21 | ||
22 | #include <X11/Xlib.h> | 22 | #include <X11/Xlib.h> |
23 | #include <X11/Xatom.h> | 23 | #include <X11/Xatom.h> |
24 | #include <X11/Xutil.h> | ||
24 | #include <string.h> | 25 | #include <string.h> |
25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
26 | #include <stdio.h> | 27 | #include <stdio.h> |
27 | 28 | ||
28 | bool g_gotError; | 29 | |
30 | bool g_gotError = false; | ||
29 | static int HandleIPCError(Display *disp, XErrorEvent*ptr) | 31 | static int HandleIPCError(Display *disp, XErrorEvent*ptr) |
30 | { | 32 | { |
31 | // ptr->error_code contains the actual error flags | 33 | // ptr->error_code contains the actual error flags |
32 | g_gotError=true; | 34 | g_gotError = true; |
33 | return( 0 ); | 35 | return( 0 ); |
34 | } | 36 | } |
35 | 37 | ||
38 | typedef int (*xerror_cb_t)(Display*,XErrorEvent*); | ||
39 | |||
40 | |||
36 | int main(int argc, char **argv) { | 41 | int main(int argc, char **argv) { |
37 | 42 | ||
43 | int rc; | ||
44 | Display* disp; | ||
45 | Window root; | ||
46 | Atom atom_utf8; | ||
47 | Atom atom_fbcmd; | ||
48 | Atom atom_result; | ||
49 | xerror_cb_t error_cb; | ||
50 | char* cmd; | ||
51 | |||
38 | if (argc <= 1) { | 52 | if (argc <= 1) { |
39 | printf("fluxbox-remote <fluxbox-command>\n"); | 53 | printf("fluxbox-remote <fluxbox-command>\n"); |
40 | return EXIT_SUCCESS; | 54 | return EXIT_SUCCESS; |
41 | } | 55 | } |
42 | 56 | ||
43 | Display *disp = XOpenDisplay(NULL); | 57 | disp = XOpenDisplay(NULL); |
44 | if (!disp) { | 58 | if (!disp) { |
45 | perror("error, can't open display."); | 59 | perror("error, can't open display."); |
46 | return EXIT_FAILURE; | 60 | return rc; |
47 | } | 61 | } |
48 | 62 | ||
49 | Atom fbcmd_atom = XInternAtom(disp, "_FLUXBOX_ACTION", False); | 63 | cmd = argv[1]; |
50 | Window root = DefaultRootWindow(disp); | 64 | atom_utf8 = XInternAtom(disp, "UTF8_STRING", False); |
65 | atom_fbcmd = XInternAtom(disp, "_FLUXBOX_ACTION", False); | ||
66 | atom_result = XInternAtom(disp, "_FLUXBOX_ACTION_RESULT", False); | ||
67 | root = DefaultRootWindow(disp); | ||
51 | 68 | ||
52 | char *str = argv[1]; | 69 | // assign the custom handler, clear the flag, sync the data, |
70 | // then check it for success/failure | ||
71 | error_cb = XSetErrorHandler(HandleIPCError); | ||
53 | 72 | ||
54 | typedef int (*x_error_handler_t)(Display*,XErrorEvent*); | ||
55 | 73 | ||
56 | // assign the custom handler, clear the flag, sync the data, then check it for success/failure | 74 | if (strcmp(cmd, "result") == 0) { |
57 | x_error_handler_t handler = XSetErrorHandler( HandleIPCError ); | 75 | XTextProperty text_prop; |
58 | g_gotError=false; | 76 | if (XGetTextProperty(disp, root, &text_prop, atom_result) != 0 |
59 | XChangeProperty(disp, root, fbcmd_atom, | 77 | && text_prop.value > 0 |
78 | && text_prop.nitems > 0) { | ||
79 | |||
80 | printf("%s", text_prop.value); | ||
81 | XFree(text_prop.value); | ||
82 | } | ||
83 | } else { | ||
84 | XChangeProperty(disp, root, atom_fbcmd, | ||
60 | XA_STRING, 8, PropModeReplace, | 85 | XA_STRING, 8, PropModeReplace, |
61 | (unsigned char *) str, strlen(str)); | 86 | (unsigned char *)cmd, strlen(cmd)); |
62 | XSync(disp,False); | 87 | XSync(disp, false); |
63 | int ret=(g_gotError?EXIT_FAILURE:EXIT_SUCCESS); | 88 | } |
64 | XSetErrorHandler(handler); | 89 | |
90 | rc = (g_gotError ? EXIT_FAILURE : EXIT_SUCCESS); | ||
65 | 91 | ||
92 | XSetErrorHandler(error_cb); | ||
66 | XCloseDisplay(disp); | 93 | XCloseDisplay(disp); |
67 | 94 | ||
68 | return ret; | 95 | return rc; |
69 | } | 96 | } |
70 | 97 | ||