Hi,

On 03.12.2013 11:06, Stanislav Ochotnicky wrote:
> Quoting Uli Schlachter (2013-12-03 08:54:22)
>> On 02.12.2013 23:39, Stanislav Ochotnicky wrote:
>>> Quoting Uli Schlachter (2013-12-02 22:57:58)
>> [...]
>>>> I hope this clears up the current state. Feel free to come up with 
>>>> suggestions
>>>> on how to improve this.
>>>
>>> Thanks for quick reply. I don't think it makes sense to complicate core 
>>> awesome
>>> codebase by introducing custom X property. It *would* be nice if completely 
>>> full
>>> dynamic tagging would be easily possible but that's not really a discussion 
>>> for
>>> this thread :-)
>>
>> I just thought about adding a "blob" property which contains just a random
>> string that is completely uninterpreted by awesome, but could be accessed by
>> lua. This blob would however need a better name than just "blob", of course.
>>
>> This isn't much work on the C side and shifts the problem into lua-land (aka 
>> "no
>> longer my problem" ;-) ).
>>
>>
>> If it were called "blob", I would save it in "AWESOME_BLOB" and have it
>> accessible as c.blob. There are some obvious problems like "who controls the
>> blob" where different modules both would want to save stuff in there. If this
>> should be solved, then "blob" would not only need a way better name, but 
>> would
>> also need to be a table. And I would have to think about how to serialize a 
>> lua
>> table into an X11 property...
> 
> I am not sure about maximum size of X11 property but I can imagine few use 
> cases
> (mostly around preserving state between restarts, saving, restoring, maybe
> profiles?)

Good question. The only thing I found in the docs:

"The maximum size of a property is server-dependent and may vary dynamically."

Anyway, attached is a patch which implements a "blob" property on clients. This
is a string that survives restarts. Of course, this needs some helper functions
in awful so that more than one thing can be saved in here. No idea about the
format for this and too lazy to think about it.

So this patch is just a proof of concept that people can experiment with. Also,
I still don't like the name "blob".

[...]
>> What do you guys think?
> 
> I'd welcome uncle blob with open arms. I believe a nice Lua access API will be
> needed but that's a separate point...

Looking forward to someone implementing this. :-)

Uli
-- 
Happiness can't be found -- it finds you.
 - Majic
diff --git a/common/atoms.list b/common/atoms.list
index 507a7ff..4c71893 100644
--- a/common/atoms.list
+++ b/common/atoms.list
@@ -1,3 +1,4 @@
+AWESOME_BLOB
 _NET_SUPPORTED
 _NET_STARTUP_ID
 _NET_CLIENT_LIST
diff --git a/objects/client.c b/objects/client.c
index bdbcaae..d59554a 100644
--- a/objects/client.c
+++ b/objects/client.c
@@ -431,6 +431,10 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, bool startup)
         return;
     }
 
+    xcb_get_property_cookie_t blob_q;
+    blob_q = xcb_get_property(globalconf.connection, false, w, AWESOME_BLOB,
+                              XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX);
+
     /* If this is a new client that just has been launched, then request its
      * startup id. */
     xcb_get_property_cookie_t startup_id_q = { 0 };
@@ -494,6 +498,19 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, bool startup)
         xcb_ungrab_server(globalconf.connection);
     }
 
+    {
+        /* Request our response */
+        xcb_get_property_reply_t *reply =
+            xcb_get_property_reply(globalconf.connection, blob_q, NULL);
+
+        if (reply)
+        {
+            c->blob.length = xcb_get_property_value_length(reply);
+            c->blob.data = p_dup((char *) xcb_get_property_value(reply), c->blob.length);
+        }
+        p_delete(&reply);
+    }
+
     /* Do this now so that we don't get any events for the above
      * (Else, reparent could cause an UnmapNotify) */
     xcb_change_window_attributes(globalconf.connection, w, XCB_CW_EVENT_MASK, select_input_val);
@@ -1763,6 +1780,13 @@ luaA_client_get_icon_name(lua_State *L, client_t *c)
     return 1;
 }
 
+static int
+luaA_client_get_blob(lua_State *L, client_t *c)
+{
+    lua_pushlstring(L, NONULL(c->blob.data), c->blob.length);
+    return 1;
+}
+
 LUA_OBJECT_EXPORT_PROPERTY(client, client_t, class, lua_pushstring)
 LUA_OBJECT_EXPORT_PROPERTY(client, client_t, instance, lua_pushstring)
 LUA_OBJECT_EXPORT_PROPERTY(client, client_t, machine, lua_pushstring)
@@ -2006,6 +2030,23 @@ luaA_client_set_shape_clip(lua_State *L, client_t *c)
     return 0;
 }
 
+/** Set the client's blob.
+ * \param L The Lua VM state.
+ * \param client The client object.
+ * \return The number of elements pushed on stack.
+ */
+static int
+luaA_client_set_blob(lua_State *L, client_t *c)
+{
+    const char *blob = luaL_checklstring(L, -1, &c->blob.length);
+
+    p_delete(&c->blob.data);
+    c->blob.data = p_dup(blob, c->blob.length);
+    xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, c->window,
+                        AWESOME_BLOB, AWESOME_BLOB, 8, c->blob.length, blob);
+    return 0;
+}
+
 /** Get or set keys bindings for a client.
  * \param L The Lua VM state.
  * \return The number of element pushed on stack.
@@ -2232,6 +2273,10 @@ client_class_setup(lua_State *L)
                             (lua_class_propfunc_t) luaA_client_set_shape_clip,
                             NULL,
                             (lua_class_propfunc_t) luaA_client_set_shape_clip);
+    luaA_class_add_property(&client_class, "blob",
+                            (lua_class_propfunc_t) luaA_client_set_blob,
+                            (lua_class_propfunc_t) luaA_client_get_blob,
+                            (lua_class_propfunc_t) luaA_client_set_blob);
 
     signal_add(&client_class.signals, "focus");
     signal_add(&client_class.signals, "list");
diff --git a/objects/client.h b/objects/client.h
index 5375418..b07e304 100644
--- a/objects/client.h
+++ b/objects/client.h
@@ -124,6 +124,11 @@ struct client_t
         /** The drawable for this bar. */
         drawable_t *drawable;
     } titlebar[CLIENT_TITLEBAR_COUNT];
+    /** The blob! */
+    struct {
+        char *data;
+        size_t length;
+    } blob;
 };
 
 ARRAY_FUNCS(client_t *, client, DO_NOTHING)

Reply via email to