parkouss / pyewmh

An implementation of EWMH (Extended Window Manager Hints) for python, based on Xlib.
GNU Lesser General Public License v3.0
40 stars 15 forks source link

BadDataError when trying to rename a window #4

Open roipoussiere opened 9 years ago

roipoussiere commented 9 years ago

I would like to rename a window, but I can't. This is an example with getActiveWindow().

#!/usr/bin/python

from ewmh import EWMH
ewmh = EWMH()

# get the active window
win = ewmh.getActiveWindow()

title = "newtitle"
print 'data length:', len(title)

# set the name
ewmh.setWmName(win, title)

# flush request
ewmh.display.flush()

Logs:

<class 'Xlib.protocol.request.QueryExtension'>
data length: 8
Traceback (most recent call last):
  File "test_2.py", line 15, in <module>
    ewmh.setWmName(win, title)
  File "/usr/local/lib/python2.7/dist-packages/ewmh/ewmh.py", line 136, in setWmName
    self._setProperty('_NET_WM_NAME', name, win)
  File "/usr/local/lib/python2.7/dist-packages/ewmh/ewmh.py", line 321, in _setProperty
    ev = protocol.event.ClientMessage(window=win, client_type=self.display.get_atom(_type), data=(dataSize, data))
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1531, in __init__
    self._binary = self._fields.to_binary(*(), **keys)
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1138, in to_binary
    return self.to_binary(*varargs, **keys)
  File "<string>", line 2, in to_binary
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 704, in pack_value
    % (value, ))
Xlib.protocol.rq.BadDataError: Wrong data length for FixedPropertyData: (8, 'newtitle')
Grimy commented 9 years ago

This is easily fixed by padding the desired title to the required length:

title += "\0" * (20 - len(title))

Maybe setWmName could be changed to do this automatically:

diff --git a/ewmh/ewmh.py b/ewmh/ewmh.py
index 1302ae6..da149ef 100644
--- a/ewmh/ewmh.py
+++ b/ewmh/ewmh.py
@@ -133,6 +133,7 @@ class EWMH:

                :param win: the window object
                :param name: desired name"""
+               name += '\0' * (20 - len(name))
                self._setProperty('_NET_WM_NAME', name, win)

        def setWmVisibleName(self, win, name):
roipoussiere commented 9 years ago

Ok, thanks, there is no error with your fix... But it doesn't rename the window.

I don't really understand why the length title needs to be fixed to 20 chars.

setWmName is not intended to rename windows.

According to pyewmh sources, setWmName() refers to the _NET_WM_NAME proterty, which is, according to the EWMH specs, should rename a window:

The Client SHOULD set this to the title of the window in UTF-8 encoding. If set, the Window Manager should use this in preference to WM_NAME.

Grimy commented 9 years ago

See X11’s documentation, D.5. The ClientMessage event's format:

char data.b[20] (read/write DATA : MAX 20 byte) If the data is smaller than 20 byte, all data other than available data must be 0.

Python’s Xlib implementation accordingly sets ClientMessage to use a fixed data size of 20:

class ClientMessage(rq.Event):
# ...
                         rq.FixedPropertyData('data', 20)