From df5974b9235a345ae68fa8ff96256ae68ab2518b Mon Sep 17 00:00:00 2001
From: markt <markt>
Date: Tue, 3 Jul 2007 18:51:15 +0000
Subject: fix updating of systemtray and kde dockapps in slit on background
 change added fluxbox-remote

---
 src/FbTk/FbPixmap.cc   | 15 ++++++++++-----
 src/FbTk/FbPixmap.hh   |  4 ++--
 src/Screen.cc          | 33 ++++++++++++++++++++++++++++++++-
 src/Screen.hh          |  5 ++++-
 src/Slit.cc            |  8 ++++++++
 src/SystemTray.cc      |  1 +
 src/fluxbox.cc         |  2 +-
 util/Makefile.am       |  5 ++++-
 util/fluxbox-remote.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 111 insertions(+), 11 deletions(-)
 create mode 100644 util/fluxbox-remote.cc

diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc
index 75dfe34..9143232 100644
--- a/src/FbTk/FbPixmap.cc
+++ b/src/FbTk/FbPixmap.cc
@@ -353,9 +353,10 @@ Pixmap FbPixmap::release() {
     return ret;
 }
 
-void FbPixmap::rootwinPropertyNotify(int screen_num, Atom atom) {
+// returns whether or not the background was changed
+bool FbPixmap::rootwinPropertyNotify(int screen_num, Atom atom) {
     if (!FbTk::Transparent::haveRender())
-        return;
+        return false;
 
     checkAtoms();
     for (int i=0; root_prop_ids[i] != 0; ++i) {
@@ -379,14 +380,16 @@ void FbPixmap::rootwinPropertyNotify(int screen_num, Atom atom) {
                 }
                 XFree(data);
                 if (root_pm != None)
-                    setRootPixmap(screen_num, root_pm);
+                    return setRootPixmap(screen_num, root_pm);
             }
-            break;
+            return false;
         }
     }
+    return false;
 }
 
-void FbPixmap::setRootPixmap(int screen_num, Pixmap pm) {
+// returns whether or not the background was changed
+bool FbPixmap::setRootPixmap(int screen_num, Pixmap pm) {
     if (!m_root_pixmaps) {
         m_root_pixmaps = new Pixmap[ScreenCount(display())];
         for (int i=0; i < ScreenCount(display()); ++i)
@@ -396,7 +399,9 @@ void FbPixmap::setRootPixmap(int screen_num, Pixmap pm) {
     if (m_root_pixmaps[screen_num] != pm) {
         m_root_pixmaps[screen_num] = pm;
         FbWindow::updatedAlphaBackground(screen_num);
+        return true;
     }
+    return false;
 }
 
 Pixmap FbPixmap::getRootPixmap(int screen_num, bool force_update) {
diff --git a/src/FbTk/FbPixmap.hh b/src/FbTk/FbPixmap.hh
index dab364a..acae07e 100644
--- a/src/FbTk/FbPixmap.hh
+++ b/src/FbTk/FbPixmap.hh
@@ -70,8 +70,8 @@ public:
     inline unsigned int depth() const { return m_depth; }
 
     static Pixmap getRootPixmap(int screen_num, bool force_update=false);
-    static void setRootPixmap(int screen_num, Pixmap pm);
-    static void rootwinPropertyNotify(int screen_num, Atom atom);
+    static bool setRootPixmap(int screen_num, Pixmap pm);
+    static bool rootwinPropertyNotify(int screen_num, Atom atom);
 
     void create(Drawable src,
                 unsigned int width, unsigned int height,
diff --git a/src/Screen.cc b/src/Screen.cc
index 293247b..55b74e1 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -348,6 +348,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
     m_currentworkspace_sig(*this), // current workspace signal
     m_reconfigure_sig(*this), // reconfigure signal
     m_resize_sig(*this),
+    m_bg_change_sig(*this),
     m_layermanager(num_layers),
     m_windowtheme(new FbWinFrameTheme(scrn)),
     // the order of windowtheme and winbutton theme is important
@@ -795,6 +796,37 @@ void BScreen::update(FbTk::Subject *subj) {
 
 }
 
+void BScreen::propertyNotify(Atom atom) {
+    static Atom fbcmd_atom = XInternAtom(FbTk::App::instance()->display(),
+                                         "_FLUXBOX_COMMAND", False);
+    if (atom == fbcmd_atom) {
+        Atom xa_ret_type;
+        int ret_format;
+        unsigned long ret_nitems, ret_bytes_after;
+        char *str;
+        if (rootWindow().property(fbcmd_atom, 0l, 64l,
+                True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
+                &ret_bytes_after, (unsigned char **)&str) && str) {
+
+            if (ret_bytes_after) {
+                XFree(str);
+                long len = 64 + (ret_bytes_after + 3)/4;
+                rootWindow().property(fbcmd_atom, 0l, len,
+                    True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
+                    &ret_bytes_after, (unsigned char **)&str);
+            }
+
+            FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(str));
+            if (cmd.get())
+                cmd->execute();
+            XFree(str);
+
+        }
+    // TODO: this doesn't belong in FbPixmap
+    } else if (FbTk::FbPixmap::rootwinPropertyNotify(screenNumber(), atom))
+        m_bg_change_sig.notify();
+}
+
 void BScreen::keyPressEvent(XKeyEvent &ke) {
     if (!m_typing_ahead) {
         Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode,
@@ -1408,7 +1440,6 @@ void BScreen::updateNetizenConfigNotify(XEvent &e) {
 
 bool BScreen::isKdeDockapp(Window client) const {
     //Check and see if client is KDE dock applet.
-    //If so add to Slit
     bool iskdedockapp = false;
     Atom ajunk;
     int ijunk;
diff --git a/src/Screen.hh b/src/Screen.hh
index 0d2534d..ce24ca7 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -237,11 +237,13 @@ public:
     /// reconfigure signal
     FbTk::Subject &reconfigureSig() { return m_reconfigure_sig; }
     FbTk::Subject &resizeSig() { return m_resize_sig; }
+    FbTk::Subject &bgChangeSig() { return m_bg_change_sig; }
     //@}
 
     /// called when the screen receives a signal from a subject
     void update(FbTk::Subject *subj);
 
+    void propertyNotify(Atom atom);
     void keyPressEvent(XKeyEvent &ke);
     void keyReleaseEvent(XKeyEvent &ke);
     void buttonPressEvent(XButtonEvent &be);
@@ -521,7 +523,8 @@ private:
         m_workspace_area_sig, ///< workspace area changed signal
         m_currentworkspace_sig, ///< current workspace signal
         m_reconfigure_sig, ///< reconfigure signal
-        m_resize_sig; ///< resize signal
+        m_resize_sig, ///< resize signal
+        m_bg_change_sig; ///< background change signal
 		
     FbTk::MultLayers m_layermanager;
 	
diff --git a/src/Slit.cc b/src/Slit.cc
index 118179b..a8e95a0 100644
--- a/src/Slit.cc
+++ b/src/Slit.cc
@@ -306,6 +306,7 @@ Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename)
     // attach to theme and root window change signal
     m_slit_theme->reconfigSig().attach(this);
     scr.resizeSig().attach(this);
+    scr.bgChangeSig().attach(this);
     scr.reconfigureSig().attach(this); // if alpha changed (we disablethis signal when we get theme change sig)
 
     scr.addConfigMenu(_FB_XTEXT(Slit, Slit, "Slit", "The Slit"), m_slitmenu);
@@ -662,6 +663,13 @@ void Slit::reconfigure() {
         // client created window?
         if ((*client_it)->window() != None && (*client_it)->visible()) {
             num_windows++;
+
+            // get the dockapps to update their backgrounds
+            if (screen().isKdeDockapp((*client_it)->window())) {
+                (*client_it)->hide();
+                (*client_it)->show();
+            }
+
             if (height_inc) {
                 // increase height of slit for each client (VERTICAL mode)
                 frame.height += (*client_it)->height() + bevel_width;
diff --git a/src/SystemTray.cc b/src/SystemTray.cc
index 04e77fa..fdccda0 100644
--- a/src/SystemTray.cc
+++ b/src/SystemTray.cc
@@ -136,6 +136,7 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen
 
     FbTk::EventManager::instance()->add(*this, m_window);
     m_theme.reconfigSig().attach(this);
+    screen.bgChangeSig().attach(this);
 
     Fluxbox* fluxbox = Fluxbox::instance();
     Display *disp = fluxbox->display();
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 5210def..57597a2 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -706,7 +706,7 @@ void Fluxbox::handleEvent(XEvent * const e) {
 
         BScreen *screen = searchScreen(e->xproperty.window);
         if (screen) {
-            FbTk::FbPixmap::rootwinPropertyNotify(screen->screenNumber(), e->xproperty.atom);
+            screen->propertyNotify(e->xproperty.atom);
         }
     }
 
diff --git a/util/Makefile.am b/util/Makefile.am
index 263c456..2033608 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -2,13 +2,14 @@
 SUBDIRS=		fbrun
 INCLUDES= 		-I$(top_srcdir)/src -I$(top_srcdir)/src/FbTk
 bin_SCRIPTS= 		fbsetbg fluxbox-generate_menu startfluxbox
-bin_PROGRAMS=		fbsetroot fluxbox-update_configs
+bin_PROGRAMS=		fbsetroot fluxbox-update_configs fluxbox-remote
 fbsetroot_SOURCES=	fbsetroot.cc fbsetroot.hh
 fbsetroot_LDADD=../src/FbRootWindow.o ../src/FbAtoms.o \
 			../src/FbTk/libFbTk.a
 fluxbox_update_configs_SOURCES=	fluxbox-update_configs.cc
 fluxbox_update_configs_LDADD=	../src/defaults.o ../src/Resources.o \
 			../src/FbTk/libFbTk.a
+fluxbox_remote_SOURCES=	fluxbox-remote.cc
 
 MAINTAINERCLEANFILES=	Makefile.in
 EXTRA_DIST=		fbsetbg fluxbox-generate_menu.in \
@@ -28,6 +29,8 @@ fbsetroot.o: 	fbsetroot.cc ../config.h $(srcdir)/fbsetroot.hh \
 fluxbox-update_configs.o:	fluxbox-update_configs.cc ../config.h \
 			$(top_srcdir)/src/defaults.hh
 
+fluxbox-remote.o:	fluxbox-remote.cc
+
 startfluxbox: 	startfluxbox.in
 		@regex_cmd@ -e "s,@pkgdatadir@,$(pkgdatadir),g" \
 		            -e "s,@pkgbindir@,$(bindir),g" \
diff --git a/util/fluxbox-remote.cc b/util/fluxbox-remote.cc
new file mode 100644
index 0000000..eb7a413
--- /dev/null
+++ b/util/fluxbox-remote.cc
@@ -0,0 +1,49 @@
+// fluxbox-remote.cc
+// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+// $Id$
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+
+    if (argc <= 1)
+        return 1;
+
+    Display *disp = XOpenDisplay(NULL);
+    if (!disp)
+        return 1;
+
+    Atom fbcmd_atom = XInternAtom(disp, "_FLUXBOX_COMMAND", False);
+    Window root = DefaultRootWindow(disp);
+
+    char *str = argv[1];
+    int ret = XChangeProperty(disp, root, fbcmd_atom,
+                              XA_STRING, 8, PropModeReplace,
+                              (unsigned char *) str, strlen(str));
+    XCloseDisplay(disp);
+
+    if (ret == Success)
+        return 0;
+    return 1;
+}
-- 
cgit v0.11.2