From 17228a9567d066268ebf071bb855219558f607db Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <fourdan.olivier@wanadoo.fr>
Date: Mon, 20 Jan 2003 12:54:35 +0000
Subject: [PATCH] Fix an issue with old gnome hints

(Old svn revision: 10847)
---
 src/client.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++----
 src/client.h |  2 ++
 src/events.c | 17 ++++++++++-
 3 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/src/client.c b/src/client.c
index 344105e73..b7a754a55 100644
--- a/src/client.c
+++ b/src/client.c
@@ -2398,21 +2398,49 @@ void clientSetWorkspace(Client * c, int ws, gboolean manage_mapping)
     }
 }
 
-void clientToggleShaded(Client * c)
+void clientShade(Client * c)
 {
     XWindowChanges wc;
 
     g_return_if_fail(c != NULL);
     DBG("entering clientToggleShaded\n");
-    DBG("shading/unshading client \"%s\" (%#lx)\n", c->name, c->window);
+    DBG("shading client \"%s\" (%#lx)\n", c->name, c->window);
 
-    if(!CLIENT_FLAG_TEST(c, CLIENT_FLAG_SHADED) && (!CLIENT_FLAG_TEST(c, CLIENT_FLAG_HAS_BORDER) || CLIENT_FLAG_TEST(c, CLIENT_FLAG_FULLSCREEN)))
+    if(!CLIENT_FLAG_TEST(c, CLIENT_FLAG_HAS_BORDER) || CLIENT_FLAG_TEST(c, CLIENT_FLAG_FULLSCREEN))
     {
         DBG("cowardly refusing to shade \"%s\" (%#lx) because it has no border\n", c->name, c->window);
         return;
     }
-    c->win_state = c->win_state ^ WIN_STATE_SHADED;
-    CLIENT_FLAG_TOGGLE(c, CLIENT_FLAG_SHADED);
+    else if(CLIENT_FLAG_TEST(c, CLIENT_FLAG_SHADED))
+    {
+        DBG("\"%s\" (%#lx) is already shaded\n", c->name, c->window);
+        return;
+    }
+
+    c->win_state |= WIN_STATE_SHADED;
+    CLIENT_FLAG_SET(c, CLIENT_FLAG_SHADED);
+    setGnomeHint(dpy, c->window, win_state, c->win_state);
+    wc.width = c->width;
+    wc.height = c->height;
+    clientSetNetState(c);
+    clientConfigure(c, &wc, CWWidth | CWHeight);
+}
+
+void clientUnshade(Client * c)
+{
+    XWindowChanges wc;
+
+    g_return_if_fail(c != NULL);
+    DBG("entering clientToggleShaded\n");
+    DBG("shading/unshading client \"%s\" (%#lx)\n", c->name, c->window);
+
+    if(!CLIENT_FLAG_TEST(c, CLIENT_FLAG_SHADED))
+    {
+        DBG("\"%s\" (%#lx) is not shaded\n", c->name, c->window);
+        return;
+    }
+    c->win_state &= ~WIN_STATE_SHADED;
+    CLIENT_FLAG_UNSET(c, CLIENT_FLAG_SHADED);
     setGnomeHint(dpy, c->window, win_state, c->win_state);
     wc.width = c->width;
     wc.height = c->height;
@@ -2420,12 +2448,41 @@ void clientToggleShaded(Client * c)
     clientConfigure(c, &wc, CWWidth | CWHeight);
 }
 
+void clientToggleShaded(Client * c)
+{
+    if(CLIENT_FLAG_TEST(c, CLIENT_FLAG_SHADED))
+    {
+        clientUnshade(c);
+    }
+    else
+    {
+        clientShade(c);
+    }
+}
+
 void clientStick(Client * c)
 {
+    int i;
+    Client *c2;
+
     g_return_if_fail(c != NULL);
     DBG("entering clientStick\n");
     DBG("sticking client \"%s\" (%#lx)\n", c->name, c->window);
 
+    if(CLIENT_FLAG_TEST(c, CLIENT_FLAG_STICKY))
+    {
+        DBG("\"%s\" (%#lx) is already sticky\n", c->name, c->window);
+        return;
+    }
+
+    for(c2 = c->next, i = 0; i < client_count; c2 = c2->next, i++)
+    {
+        if((c2->transient_for == c->window) && (c2 != c) && !CLIENT_FLAG_TEST(c2, CLIENT_FLAG_STICKY))
+        {
+            clientStick(c2);
+        }
+    }
+
     c->win_state |= WIN_STATE_STICKY;
     CLIENT_FLAG_SET(c, CLIENT_FLAG_STICKY);
     setGnomeHint(dpy, c->window, win_state, c->win_state);
@@ -2435,10 +2492,27 @@ void clientStick(Client * c)
 
 void clientUnstick(Client * c)
 {
+    int i;
+    Client *c2;
+
     g_return_if_fail(c != NULL);
     DBG("entering clientUnstick\n");
     DBG("unsticking client \"%s\" (%#lx)\n", c->name, c->window);
 
+    if(!CLIENT_FLAG_TEST(c, CLIENT_FLAG_STICKY))
+    {
+        DBG("\"%s\" (%#lx) is not sticky\n", c->name, c->window);
+        return;
+    }
+
+    for(c2 = c->next, i = 0; i < client_count; c2 = c2->next, i++)
+    {
+        if((c2->transient_for == c->window) && (c2 != c) && CLIENT_FLAG_TEST(c2, CLIENT_FLAG_STICKY))
+        {
+            clientUnstick(c2);
+        }
+    }
+
     c->win_state &= ~WIN_STATE_STICKY;
     CLIENT_FLAG_UNSET(c, CLIENT_FLAG_STICKY);
     setGnomeHint(dpy, c->window, win_state, c->win_state);
diff --git a/src/client.h b/src/client.h
index ee901709e..656c24063 100644
--- a/src/client.h
+++ b/src/client.h
@@ -209,6 +209,8 @@ void clientRaise(Client *);
 void clientLower(Client *);
 void clientSetLayer(Client *, int);
 void clientSetWorkspace(Client *, int, gboolean);
+void clientShade(Client *);
+void clientUnshade(Client *);
 void clientToggleShaded(Client *);
 void clientStick(Client *);
 void clientUnstick(Client *);
diff --git a/src/events.c b/src/events.c
index fb68c1481..3dead2be3 100644
--- a/src/events.c
+++ b/src/events.c
@@ -845,12 +845,27 @@ static inline void handleClientMessage(XClientMessageEvent * ev)
         else if((ev->message_type == win_state) && (ev->format == 32) && (ev->data.l[0] & WIN_STATE_SHADED))
         {
             DBG("client \"%s\" (%#lx) has received a win_state/shaded event\n", c->name, c->window);
+	    if (ev->data.l[1] == WIN_STATE_SHADED)
+	    {
+                clientShade(c);
+	    }
+	    else
+	    {
+                clientUnshade(c);
+	    }
             clientToggleShaded(c);
         }
         else if((ev->message_type == win_state) && (ev->format == 32) && (ev->data.l[0] & WIN_STATE_STICKY))
         {
             DBG("client \"%s\" (%#lx) has received a win_state/stick event\n", c->name, c->window);
-            clientToggleSticky(c);
+	    if (ev->data.l[1] == WIN_STATE_STICKY)
+	    {
+                clientStick(c);
+	    }
+	    else
+	    {
+                clientUnstick(c);
+	    }
         }
         else if((ev->message_type == win_layer) && (ev->format == 32))
         {
-- 
GitLab