From 16c567638cad8b0fdd5afb08ae7a185f5259e4c1 Mon Sep 17 00:00:00 2001
From: rathnor <rathnor>
Date: Fri, 4 Jul 2003 14:06:20 +0000
Subject: fix winclient death signalling

---
 ChangeLog             |   4 +
 src/AtomHandler.hh    |   5 +-
 src/Ewmh.hh           |   5 +-
 src/Gnome.hh          |   5 +-
 src/Remember.cc       | 218 +++++++++++++++++++++++++-------------------------
 src/Remember.hh       |   5 +-
 src/ToolbarHandler.cc |   4 +-
 src/ToolbarHandler.hh |   5 +-
 src/fluxbox.cc        |  13 +--
 9 files changed, 137 insertions(+), 127 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2779cc5..b465e17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 (Format: Year/Month/Day)
 Changes for 0.9.4:
+*03/07/05:
+   * Fix winclient death signalling - fixes remember issues with applying
+     attributes to wrong windows (Simon)
+     Remember.hh/cc AtomHandler.hh fluxbox.cc ToolbarHandler.hh/cc Ewmh.hh Gnome.hh
 *03/07/04:
    * Add support in remember for grouping apps (Simon)
      Achieved by using [group], e.g.
diff --git a/src/AtomHandler.hh b/src/AtomHandler.hh
index 4b47e15..7212ff7 100644
--- a/src/AtomHandler.hh
+++ b/src/AtomHandler.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: AtomHandler.hh,v 1.9 2003/07/04 01:03:40 rathnor Exp $
+// $Id: AtomHandler.hh,v 1.10 2003/07/04 14:06:20 rathnor Exp $
 
 #ifndef ATOMHANDLER_HH
 #define ATOMHANDLER_HH
@@ -43,7 +43,8 @@ public:
     virtual void updateCurrentWorkspace(BScreen &screen) = 0;
     virtual void updateWorkspaceCount(BScreen &screen) = 0;
 
-    virtual void updateWindowClose(FluxboxWindow &win) = 0;
+    virtual void updateFrameClose(FluxboxWindow &win) = 0;
+    virtual void updateClientClose(WinClient &winclient) = 0;
     virtual void updateWorkspace(FluxboxWindow &win) = 0;
     virtual void updateState(FluxboxWindow &win) = 0;
     virtual void updateHints(FluxboxWindow &win) = 0;
diff --git a/src/Ewmh.hh b/src/Ewmh.hh
index ff508e5..206f36e 100644
--- a/src/Ewmh.hh
+++ b/src/Ewmh.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Ewmh.hh,v 1.8 2003/07/04 01:03:40 rathnor Exp $
+// $Id: Ewmh.hh,v 1.9 2003/07/04 14:06:20 rathnor Exp $
 
 #include "AtomHandler.hh"
 
@@ -51,7 +51,8 @@ public:
 
     bool propertyNotify(FluxboxWindow &win, Atom the_property);
     //ignore these ones
-    void updateWindowClose(FluxboxWindow &win) {}
+    void updateFrameClose(FluxboxWindow &win) {}
+    void updateClientClose(WinClient &winclient) {}
 
 private:
 	
diff --git a/src/Gnome.hh b/src/Gnome.hh
index 35e25c8..a9a63f5 100644
--- a/src/Gnome.hh
+++ b/src/Gnome.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Gnome.hh,v 1.8 2003/07/04 01:03:40 rathnor Exp $
+// $Id: Gnome.hh,v 1.9 2003/07/04 14:06:20 rathnor Exp $
 
 #ifndef GNOME_HH
 #define GNOME_HH
@@ -81,7 +81,8 @@ public:
     bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win);
 	
     // ignore these ones
-    void updateWindowClose(FluxboxWindow &win) {}
+    void updateFrameClose(FluxboxWindow &win) {}
+    void updateClientClose(WinClient &winclient) {}
     bool propertyNotify(FluxboxWindow &win, Atom the_property) { return false; }
 
 private:
diff --git a/src/Remember.cc b/src/Remember.cc
index 97d1e35..0b4b248 100644
--- a/src/Remember.cc
+++ b/src/Remember.cc
@@ -21,7 +21,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Remember.cc,v 1.25 2003/07/04 01:03:40 rathnor Exp $
+// $Id: Remember.cc,v 1.26 2003/07/04 14:06:20 rathnor Exp $
 
 #include "Remember.hh"
 #include "ClientPattern.hh"
@@ -216,94 +216,94 @@ int Remember::parseApp(ifstream &file, Application &app, string *first_line) {
             }
 
             row++;
-            if (line[0] != '#') { //the line is commented
-                int parse_pos = 0, err = 0;
-                string str_key, str_label;
-                err = FbTk::StringUtil::getStringBetween(str_key, 
-                                                         line.c_str(), 
-                                                         '[', ']');
-                if (err > 0 ) {
+            if (line[0] == '#')
+                continue;  //the line is commented
+            int parse_pos = 0, err = 0;
+            string str_key, str_label;
+            err = FbTk::StringUtil::getStringBetween(str_key, 
+                                                     line.c_str(), 
+                                                     '[', ']');
+            if (err > 0 ) {
+                parse_pos += err;
+                err = FbTk::StringUtil::getStringBetween(str_label, 
+                                                         line.c_str() + parse_pos, 
+                                                         '{', '}');
+                if (err>0) {
                     parse_pos += err;
-                    err = FbTk::StringUtil::getStringBetween(str_label, 
-                                                       line.c_str() + parse_pos, 
-                                                       '{', '}');
-                    if (err>0) {
-                        parse_pos += err;
-                    }
-                } else
-                    continue; //read next line
-
-                if (!str_key.size())
-                    continue; //read next line
-                if (str_key == "Workspace") {
-                    unsigned int w;
-                    istringstream iss(str_label.c_str());
-                    iss >> w;
-                    app.rememberWorkspace(w);
-                } else if (str_key == "Layer") {
-                    unsigned int l;
-                    istringstream iss(str_label.c_str());
-                    iss >> l;
-                    app.rememberLayer(l);
-                } else if (str_key == "Dimensions") {
-                    unsigned int h,w;
-                    istringstream iss(str_label.c_str());
-                    iss >> w >> h;
-                    app.rememberDimensions(w,h);
-                } else if (str_key == "Position") {
-                    unsigned int x,y;
-                    istringstream iss(str_label);
-                    iss >> x >> y;
-                    app.rememberPosition(x,y);
-                } else if (str_key == "Shaded") {
-                    app.rememberShadedstate((str_label=="yes"));
-                } else if (str_key == "Tab") {
-                    app.rememberTabstate((str_label=="yes"));
-                } else if (str_key == "Deco") {
-                    if (str_label == "NONE") {
-                        app.rememberDecostate((unsigned int) 0);
-                    } else if (str_label == "NORMAL") {
-                        app.rememberDecostate((unsigned int) 0xfffffff);
-                    } else if (str_label == "TINY") {
-                        app.rememberDecostate((unsigned int)
-                                             FluxboxWindow::DECORM_TITLEBAR 
-                                             | FluxboxWindow::DECORM_ICONIFY
-                                             | FluxboxWindow::DECORM_MENU
-                                             );
-                    } else if (str_label == "TOOL") {
-                        app.rememberDecostate((unsigned int)
-                                             FluxboxWindow::DECORM_TITLEBAR
-                                             | FluxboxWindow::DECORM_MENU
-                                             );
-                    } else if (str_label == "BORDER") {
-                        app.rememberDecostate((unsigned int)
-                                             FluxboxWindow::DECORM_BORDER
-                                             | FluxboxWindow::DECORM_MENU
-                                             );
-                    } else {
-                        unsigned int mask;
-                        const char * str = str_label.c_str();
-                        // it'll have at least one char and \0, so this is safe
-                        istringstream iss(str);
-                        // check for hex
-                        if (str[0] == '0' && str[1] == 'x') {
-                            iss.seekg(2);
-                            iss >> hex;
-                        }
-                        iss >> mask ;
-                        app.rememberDecostate(mask);
-                    }
-                } else if (str_key == "Sticky") {
-                    app.rememberStuckstate((str_label=="yes"));
-                } else if (str_key == "Jump") {
-                    app.rememberJumpworkspace((str_label=="yes"));
-                } else if (str_key == "Close") {
-                    app.rememberSaveOnClose((str_label=="yes"));
-                } else if (str_key == "end") {
-                    return row;
+                }
+            } else
+                continue; //read next line
+
+            if (!str_key.size())
+                continue; //read next line
+            if (str_key == "Workspace") {
+                unsigned int w;
+                istringstream iss(str_label.c_str());
+                iss >> w;
+                app.rememberWorkspace(w);
+            } else if (str_key == "Layer") {
+                unsigned int l;
+                istringstream iss(str_label.c_str());
+                iss >> l;
+                app.rememberLayer(l);
+            } else if (str_key == "Dimensions") {
+                unsigned int h,w;
+                istringstream iss(str_label.c_str());
+                iss >> w >> h;
+                app.rememberDimensions(w,h);
+            } else if (str_key == "Position") {
+                unsigned int x,y;
+                istringstream iss(str_label);
+                iss >> x >> y;
+                app.rememberPosition(x,y);
+            } else if (str_key == "Shaded") {
+                app.rememberShadedstate((str_label=="yes"));
+            } else if (str_key == "Tab") {
+                app.rememberTabstate((str_label=="yes"));
+            } else if (str_key == "Deco") {
+                if (str_label == "NONE") {
+                    app.rememberDecostate((unsigned int) 0);
+                } else if (str_label == "NORMAL") {
+                    app.rememberDecostate((unsigned int) 0xfffffff);
+                } else if (str_label == "TINY") {
+                    app.rememberDecostate((unsigned int)
+                                          FluxboxWindow::DECORM_TITLEBAR 
+                                          | FluxboxWindow::DECORM_ICONIFY
+                                          | FluxboxWindow::DECORM_MENU
+                        );
+                } else if (str_label == "TOOL") {
+                    app.rememberDecostate((unsigned int)
+                                          FluxboxWindow::DECORM_TITLEBAR
+                                          | FluxboxWindow::DECORM_MENU
+                        );
+                } else if (str_label == "BORDER") {
+                    app.rememberDecostate((unsigned int)
+                                          FluxboxWindow::DECORM_BORDER
+                                          | FluxboxWindow::DECORM_MENU
+                        );
                 } else {
-                    cerr << "Unsupported apps key = " << str_key << endl;
+                    unsigned int mask;
+                    const char * str = str_label.c_str();
+                    // it'll have at least one char and \0, so this is safe
+                    istringstream iss(str);
+                    // check for hex
+                    if (str[0] == '0' && str[1] == 'x') {
+                        iss.seekg(2);
+                        iss >> hex;
+                    }
+                    iss >> mask ;
+                    app.rememberDecostate(mask);
                 }
+            } else if (str_key == "Sticky") {
+                app.rememberStuckstate((str_label=="yes"));
+            } else if (str_key == "Jump") {
+                app.rememberJumpworkspace((str_label=="yes"));
+            } else if (str_key == "Close") {
+                app.rememberSaveOnClose((str_label=="yes"));
+            } else if (str_key == "end") {
+                return row;
+            } else {
+                cerr << "Unsupported apps key = " << str_key << endl;
             }
         }
     }
@@ -684,35 +684,35 @@ void Remember::setupClient(WinClient &winclient) {
     }
 }
 
-void Remember::updateWindowClose(FluxboxWindow &win) {
-    // This doesn't work at present since fluxbox.cc is missing the windowclose stuff.
-    // I don't trust it (particularly winClient()) while this is the case
+void Remember::updateClientClose(WinClient &winclient) {
+    Application *app = find(winclient);
+
+    if (app && (app->save_on_close_remember && app->save_on_close)) {
 
-    // scan all winclients and remove this fbw
-    Patterns::iterator it = m_pats.begin();
-    while (it != m_pats.end()) {
-        if (&win == it->second->group)
-            it->second->group = 0;
-        ++it;
-    }
+        for (int attrib = 0; attrib <= REM_LASTATTRIB; attrib++) {
+            if (isRemembered(winclient, (Attribute) attrib)) {
+                rememberAttrib(winclient, (Attribute) attrib);
+            }
+        }
 
-    return;
+        save();
+    }
 
-    WinClient &winclient = win.winClient();
-    Application *app = find(winclient);
-    Clients::iterator wc_it = m_clients.find(&win.winClient());
+    // we need to get rid of references to this client
+    Clients::iterator wc_it = m_clients.find(&winclient);
 
-    if (wc_it != m_clients.end())
+    if (wc_it != m_clients.end()) {
         m_clients.erase(wc_it);
+    }
 
-    if (!app || !(app->save_on_close_remember && app->save_on_close))
-        return;
+}
 
-    for (int attrib = 0; attrib <= REM_LASTATTRIB; attrib++) {
-        if (isRemembered(winclient, (Attribute) attrib)) {
-            rememberAttrib(winclient, (Attribute) attrib);
-        }
+void Remember::updateFrameClose(FluxboxWindow &win) {
+    // scan all applications and remove this fbw if it is a recorded group
+    Patterns::iterator it = m_pats.begin();
+    while (it != m_pats.end()) {
+        if (&win == it->second->group)
+            it->second->group = 0;
+        ++it;
     }
-
-    save();
 }
diff --git a/src/Remember.hh b/src/Remember.hh
index 756bc7f..c687137 100644
--- a/src/Remember.hh
+++ b/src/Remember.hh
@@ -21,7 +21,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Remember.hh,v 1.9 2003/07/04 01:03:40 rathnor Exp $
+// $Id: Remember.hh,v 1.10 2003/07/04 14:06:20 rathnor Exp $
 
 /* Based on the original "Remember patch" by Xavier Brouckaert */
 
@@ -166,7 +166,8 @@ public:
     // Functions we actually use
     void setupFrame(FluxboxWindow &win);
     void setupClient(WinClient &winclient);
-    void updateWindowClose(FluxboxWindow &win);
+    void updateFrameClose(FluxboxWindow &win);
+    void updateClientClose(WinClient &winclient);
 
     // Functions we ignore (zero from AtomHandler)
     // Leaving here in case they might be useful later
diff --git a/src/ToolbarHandler.cc b/src/ToolbarHandler.cc
index 61949ce..152ed67 100644
--- a/src/ToolbarHandler.cc
+++ b/src/ToolbarHandler.cc
@@ -20,7 +20,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: ToolbarHandler.cc,v 1.20 2003/07/04 01:03:40 rathnor Exp $
+// $Id: ToolbarHandler.cc,v 1.21 2003/07/04 14:06:20 rathnor Exp $
 
 /**
  * The ToolbarHandler class acts as a rough interface to the toolbar.
@@ -295,7 +295,7 @@ void ToolbarHandler::setupFrame(FluxboxWindow &win) {
     }
 }
 
-void ToolbarHandler::updateWindowClose(FluxboxWindow &win) {
+void ToolbarHandler::updateFrameClose(FluxboxWindow &win) {
     if (&win.screen() != &m_screen) 
         return;
 
diff --git a/src/ToolbarHandler.hh b/src/ToolbarHandler.hh
index f0c470d..a8b31cf 100644
--- a/src/ToolbarHandler.hh
+++ b/src/ToolbarHandler.hh
@@ -20,7 +20,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: ToolbarHandler.hh,v 1.5 2003/07/04 01:03:40 rathnor Exp $
+// $Id: ToolbarHandler.hh,v 1.6 2003/07/04 14:06:20 rathnor Exp $
 
 #ifndef TOOLBARHANDLER_HH
 #define TOOLBARHANDLER_HH
@@ -61,7 +61,8 @@ public:
     void setupClient(WinClient &winclient) {}
     
     void updateState(FluxboxWindow &win);
-    void updateWindowClose(FluxboxWindow &win);
+    void updateFrameClose(FluxboxWindow &win);
+    void updateClientClose(WinClient &winclient) {}
     void updateWorkspace(FluxboxWindow &win);
     void updateCurrentWorkspace(BScreen &screen);
 
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index cb5cb68..75a6502 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: fluxbox.cc,v 1.168 2003/07/04 01:03:41 rathnor Exp $
+// $Id: fluxbox.cc,v 1.169 2003/07/04 14:06:20 rathnor Exp $
 
 #include "fluxbox.hh"
 
@@ -1262,7 +1262,7 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
         } else if ((&(win.dieSig())) == changedsub) { // window death signal
             for (size_t i=0; i<m_atomhandler.size(); ++i) {
                 if (m_atomhandler[i]->update())
-                    m_atomhandler[i]->updateWindowClose(win);
+                    m_atomhandler[i]->updateFrameClose(win);
             }
             // make sure each workspace get this 
             BScreen &scr = win.screen();
@@ -1309,15 +1309,16 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
         WinClient::WinClientSubj *subj = dynamic_cast<WinClient::WinClientSubj *>(changedsub);
         WinClient &client = subj->winClient();
 
+        // TODO: don't assume it is diesig (need to fix as soon as another signal appears)
+        for (size_t i=0; i<m_atomhandler.size(); ++i) {
+            if (m_atomhandler[i]->update())
+                m_atomhandler[i]->updateClientClose(client);
+        }
         BScreen &screen = client.screen();
         screen.updateNetizenWindowDel(client.window());
         screen.removeClient(client);
 
         removeWindowSearch(client.window());        
-        //!! TODO
-#ifdef DEBUG
-        cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO: signal stuff for client death!!"<<endl;
-#endif // DEBUG
     }
 }
 
-- 
cgit v0.11.2