X Tutup
The Wayback Machine - https://web.archive.org/web/20210106131100/https://github.com/python-xlib/python-xlib/issues/54
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display.get_input_focus().focus results in infinite 100% loop after Window.get_wm_name errors out. #54

Closed
NAMB-develop opened this issue Aug 8, 2016 · 9 comments
Labels

Comments

@NAMB-develop
Copy link

@NAMB-develop NAMB-develop commented Aug 8, 2016

I am running the latest Xlib and using RECORD extension (almost same code as examples/recorder_demo.py).
I try to access the window title name, handle and class when a keyboard event occurs.
w = self.local_dpy.get_input_focus().focus
wm = w.get_wm_name()
However, if the window title contains a non-ascii character, such as '·', the get_wm_name excepts with a UnicodeDecodeError: 'ascii' codec can't decode byte 0xb7 in position 10: ordinal not in range(128).
That would not be a problem on itself. But, on the next event, when get_input_focus() is called again, it never returns and boosts CPU usage to 100%.

To reproduce this you could open any browser window and browse to github, because github uses '·' regularly in their page titles.

I am running python2.7

@vasily-v-ryabov vasily-v-ryabov added this to the python-xlib 0.17 milestone Aug 8, 2016
@benoit-pierre
Copy link
Member

@benoit-pierre benoit-pierre commented Aug 8, 2016

Did you try with the current master? A fix was recently pushed for properties handling.

@NAMB-develop
Copy link
Author

@NAMB-develop NAMB-develop commented Aug 8, 2016

@benoit-pierre Yes I am quite sure. Are you referring to the commit from 6 days ago? I pulled from master 3 days ago.

@NAMB-develop
Copy link
Author

@NAMB-develop NAMB-develop commented Aug 8, 2016

When you press ctrl+C when it never returns, it traces back to:
https://github.com/python-xlib/python-xlib/blob/master/Xlib/protocol/rq.py#L1362
Might it be the case that that while loop keeps looping forever?

@benoit-pierre
Copy link
Member

@benoit-pierre benoit-pierre commented Aug 8, 2016

Can you provide a full stack trace? A link to the Recorder program would help too.

@NAMB-develop
Copy link
Author

@NAMB-develop NAMB-develop commented Aug 8, 2016

I discovered it using pyxhook, which can be retrieved from:
https://github.com/JeffHoogland/pyxhook/blob/master/pyxhook.py

The function that is raising the error is:
https://github.com/JeffHoogland/pyxhook/blob/master/pyxhook.py#L277

And the UnicodeDecodeError error occurs at line:
https://github.com/JeffHoogland/pyxhook/blob/master/pyxhook.py#L280

In the next event, it never returns from:
https://github.com/JeffHoogland/pyxhook/blob/master/pyxhook.py#L279

I am not on my linux pc right now. Therefore I cannot provide a full stack trace. Will add when I am able to.

@benoit-pierre
Copy link
Member

@benoit-pierre benoit-pierre commented Aug 8, 2016

So when you say Recorder, you mean using the RECORD extension, not a particular program?

If I use the example.py program of pyxhook.py, I do get an error because the code does str(self.WindowName), which is invalid: it's equivalent to self.WindowName.encode('ascii'), and result in a exception because of the latin1 character · . See this comment about how string properties work.

@NAMB-develop
Copy link
Author

@NAMB-develop NAMB-develop commented Aug 8, 2016

(Yes I meant RECORD extension)

That is odd, because I definitely get the error at:
https://github.com/JeffHoogland/pyxhook/blob/master/pyxhook.py#L280 and sometimes at https://github.com/JeffHoogland/pyxhook/blob/master/pyxhook.py#L289 (same function though).
When I put a try except block around this specific line and print the error, it prints:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xb7 in position 10: ordinal not in range(128).

@benoit-pierre
Copy link
Member

@benoit-pierre benoit-pierre commented Aug 8, 2016

Using the following patch:

diff --git i/pyxhook.py w/pyxhook.py
index c751001..a24a670 100644
--- i/pyxhook.py
+++ w/pyxhook.py
@@ -275,12 +275,14 @@ class HookManager(threading.Thread):
         return pyxhookmouseevent(storewm["handle"], storewm["name"], storewm["class"], (self.mouse_position_x, self.mouse_position_y), MessageName)

     def xwindowinfo(self):
+        from traceback import print_exc
         try:
             windowvar = self.local_dpy.get_input_focus().focus
             wmname = windowvar.get_wm_name()
             wmclass = windowvar.get_wm_class()
             wmhandle = str(windowvar)[20:30]
         except:
+            print_exc()
             ## This is to keep things running smoothly. It almost never happens, but still...
             return {"name":None, "class":None, "handle":None}
         if (wmname == None) and (wmclass == None):
@@ -290,6 +292,7 @@ class HookManager(threading.Thread):
                 wmclass = windowvar.get_wm_class()
                 wmhandle = str(windowvar)[20:30]
             except:
+                print_exc()
                 ## This is to keep things running smoothly. It almost never happens, but still...
                 return {"name":None, "class":None, "handle":None}
         if wmclass == None:

I get this with python-xlib-0.16:

Traceback (most recent call last):
  File "/home/bpierre/progs/src/pyxhook/pyxhook.py", line 291, in xwindowinfo
    wmname = windowvar.get_wm_name()
  File "build/bdist.linux-x86_64/egg/Xlib/xobject/drawable.py", line 644, in get_wm_name
    d = self.get_full_property(Xatom.WM_NAME, Xatom.STRING)
  File "build/bdist.linux-x86_64/egg/Xlib/xobject/drawable.py", line 465, in get_full_property
    prop.bytes_after // 4 + 1)
  File "build/bdist.linux-x86_64/egg/Xlib/xobject/drawable.py", line 449, in get_property
    long_length = length)
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/rq.py", line 1361, in __init__
    self.reply()
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/rq.py", line 1373, in reply
    self._display.send_and_recv(request = self._serial)
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/display.py", line 576, in send_and_recv
    gotreq = self.parse_response(request)
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/display.py", line 668, in parse_response
    gotreq = self.parse_request_response(request) or gotreq
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/display.py", line 756, in parse_request_response
    req._parse_response(self.data_recv[:self.recv_packet_len])
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/rq.py", line 1385, in _parse_response
    self._data, d = self._reply.parse_binary(data, self._display, rawdict = 1)
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/rq.py", line 1197, in parse_binary
    formats.get(f.name),
  File "build/bdist.linux-x86_64/egg/Xlib/protocol/rq.py", line 653, in parse_binary_value
    ret = (8, data[:length].decode())
UnicodeDecodeError: 'ascii' codec can't decode byte 0xb7 in position 59: ordinal not in range(128)

And this with the current master:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/home/bpierre/progs/src/pyxhook/pyxhook.py", line 112, in run
    self.record_dpy.record_enable_context(self.ctx, self.processevents)
  File "/home/bpierre/progs/src/python-xlib/Xlib/ext/record.py", line 243, in enable_context
    context = context)
  File "/home/bpierre/progs/src/python-xlib/Xlib/ext/record.py", line 220, in __init__
    rq.ReplyRequest.__init__(self, *args, **keys)
  File "/home/bpierre/progs/src/python-xlib/Xlib/protocol/rq.py", line 1360, in __init__
    self.reply()
  File "/home/bpierre/progs/src/python-xlib/Xlib/protocol/rq.py", line 1372, in reply
    self._display.send_and_recv(request = self._serial)
  File "/home/bpierre/progs/src/python-xlib/Xlib/protocol/display.py", line 576, in send_and_recv
    gotreq = self.parse_response(request)
  File "/home/bpierre/progs/src/python-xlib/Xlib/protocol/display.py", line 668, in parse_response
    gotreq = self.parse_request_response(request) or gotreq
  File "/home/bpierre/progs/src/python-xlib/Xlib/protocol/display.py", line 756, in parse_request_response
    req._parse_response(self.data_recv[:self.recv_packet_len])
  File "/home/bpierre/progs/src/python-xlib/Xlib/ext/record.py", line 224, in _parse_response
    self._callback(r)
  File "/home/bpierre/progs/src/pyxhook/pyxhook.py", line 153, in processevents
    self.KeyDown(hookevent)
  File "example.py", line 14, in kbevent
    print event
  File "/home/bpierre/progs/src/pyxhook/pyxhook.py", line 328, in __str__
    return "Window Handle: " + str(self.Window) + "\nWindow Name: " + str(self.WindowName) + "\nWindow's Process Name: " + str(self.WindowProcName) + "\nKey Pressed: " + str(self.Key) + "\nAscii Value: " + str(self.Ascii) + "\nKeyID: " + str(self.KeyID) + "\nScanCode: " + str(self.ScanCode) + "\nMessageName: " + str(self.MessageName) + "\n"
UnicodeEncodeError: 'ascii' codec can't encode character u'\xb7' in position 99: ordinal not in range(128)

So are you sure you're using the right version?

@NAMB-develop
Copy link
Author

@NAMB-develop NAMB-develop commented Aug 8, 2016

I feel embarassed, but it is my own mistake. benoit-pierre is right. I had a zombied installation of Xlib (0.16). After reinstalling from master and rebooting, it was fixed. I will do a pull request for pyxhook to get the code fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.
X Tutup