Giter Site home page Giter Site logo

python-xlib / python-xlib Goto Github PK

View Code? Open in Web Editor NEW
416.0 18.0 109.0 1.24 MB

XLib in pure Python (Py2/Py3 compatible)

License: GNU Lesser General Public License v2.1

Python 99.78% Awk 0.20% Shell 0.01%
xlib python python3 python2 linux python-2 python-3 python-library

python-xlib's Introduction

The Python X Library

Build Status codecov.io Code Health

Homepage | Releases | Changelog

The main part of the code is

Copyright (C) 2000-2002  Peter Liljenberg

Some contributed code is copyrighted by the contributors, in these cases that is indicated in the source files in question.

The Python X Library is released under LGPL v2.1 or later (since 2016), see the file LICENSE for details. 0.15rc1 and before were released under GPL v2.

Requirements

The Python X Library requires Python 2.7 or newer. It has been tested to various extents with Python 2.7 and 3.3 through 3.6.

The Python X Library will only work on systems that have an X server installed, such as most Linux distros, but will not work on Windows or MacOS.

Installation

The Python Xlib uses the standard setuptools package, to install run this command:

python setup.py install

See the command help for details: python setup.py install -h.

Alternatively, you can run programs from the distribution directory, or change the module path in programs.

There's a simple example program, implemented twice using both the high-level interface and the low-level protocol.

Introduction

The Python X Library is intended to be a fully functional X client library for Python programs. It is written entirely in Python, in contrast to earlier X libraries for Python (the ancient X extension and the newer plxlib) which were interfaces to the C Xlib.

This is possible to do since X client programs communicate with the X server via the X protocol. The communication takes place over TCP/IP, Unix sockets, DECnet or any other streaming network protocol. The C Xlib is merely an interface to this protocol, providing functions suitable for a C environment.

There are three advantages of implementing a pure Python library:

  • Integration: The library can make use of the wonderful object system in Python, providing an easy-to-use class hierarchy.
  • Portability: The library will be usable on (almost) any computer which have Python installed. A C interface could be problematic to port to non-Unix systems, such as MS Windows or OpenVMS.
  • Maintainability: It is much easier to develop and debug native Python modules than modules written in C.

Documentation

The reference manual is not finished by far, but is probably still useful. It can be browsed online.

There are also some example programs and, of course, the standard X11 documentation applies.

Project status

The low-level protocol is complete, implementing client-side X11R6. The high-level object oriented interface is also fully functional. It is possible to write client applications with the library. Currently, the only real application using Python Xlib is the window manager PLWM, starting with version 2.0.

There is a resource database implementation, ICCCM support and a framework for adding X extension code. Several extensions have been implemented (RECORD, SHAPE, Xinerama, Composite, RANDR, DAMAGE, Generic Event, SECURITY, XFIXES, XInput, XTEST, NV-CONTROL, DPMS and XRes); patches for additions are very welcome.

There are most likely still bugs, but the library is at least stable enough to run PLWM. A continuously bigger part of the library is covered by regression tests, improving stability.

The documentation is still quite rudimentary, but should be of some help for people programming with the Xlib. X beginners should first find some general texts on X. A very good starting point is http://www.rahul.net/kenton/xsites.html

See the file TODO for a detailed list of what is missing, approximately ordered by importance.

python-xlib's People

Contributors

acrisci avatar alebastr avatar allfro avatar avasam avatar benoit-pierre avatar blechschmidt avatar calroc avatar cclauss avatar forestbond avatar frafra avatar i2y avatar ingolemo avatar jakogut avatar jklong avatar kwadrat avatar leinardi avatar mgarg1 avatar mikeggrant avatar mwm avatar opoplawski avatar petli avatar precondition avatar sebelino avatar svetlanafilicheva avatar t-wissmann avatar takluyver avatar thiagokokada avatar tkhanova avatar vasily-v-ryabov avatar whitelynx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-xlib's Issues

Connecting to local X server fails in Windows Subsystem for Linux (trying to use Unix socket)

I'm running Ubuntu on Windows with an X server as detailed here. Emacs and other Xlib generally work fine. However, apps using python-xlib break.

With DISPLAY=:0, the smallest piece of code that breaks is the following:

import Xlib.display

display = Xlib.display.Display()
display.close()

with the following error:

Traceback (most recent call last):
  File "/home/mao/projects/python-xlib/Xlib/support/unix_connect.py", line 105, in get_socket
    s.connect(address)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "xlib.py", line 3, in <module>
    display = Xlib.display.Display()
  File "/home/mao/projects/python-xlib/Xlib/display.py", line 89, in __init__
    self.display = _BaseDisplay(display)
  File "/home/mao/projects/python-xlib/Xlib/display.py", line 71, in __init__
    protocol_display.Display.__init__(self, *args, **keys)
  File "/home/mao/projects/python-xlib/Xlib/protocol/display.py", line 94, in __init__
    self.socket = connect.get_socket(name, host, displayno)
  File "/home/mao/projects/python-xlib/Xlib/support/connect.py", line 86, in get_socket
    return mod.get_socket(dname, host, dno)
  File "/home/mao/projects/python-xlib/Xlib/support/unix_connect.py", line 107, in get_socket
    raise error.DisplayConnectionError(dname, str(val))
Xlib.error.DisplayConnectionError: Can't connect to display ":0": [Errno 111] Connection refused

I've narrowed it down to this line, which seems to be trying to use a Unix socket that wouldn't exist on WSL. (The X server is running on Windows).

If I try using DISPLAY=localhost:0 instead, which by that code seems to force a TCP connection, it seems like a connection happens, but I get a different error. I can't really figure out what is causing this.

Traceback (most recent call last):
  File "/home/mao/projects/python-xlib/Xlib/display.py", line 224, in __getattr__
    function = self.display_extension_methods[attr]
KeyError: 'ge_add_event_data'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "xlib.py", line 3, in <module>
    display = Xlib.display.Display()
  File "/home/mao/projects/python-xlib/Xlib/display.py", line 127, in __init__
    mod.init(self, info)
  File "/home/mao/projects/python-xlib/Xlib/ext/xinput.py", line 652, in init
    disp.ge_add_event_data(info.major_opcode, device_event, DeviceEventData)
  File "/home/mao/projects/python-xlib/Xlib/display.py", line 227, in __getattr__
    raise AttributeError(attr)
AttributeError: ge_add_event_data

Given that apps using Xlib seem to work fine (with both DISPLAY=:0 and DISPLAY=localhost:0), is there some way we can fix the socket code to be more robust in this situation? I tried browsing the Xlib source but couldn't figure out how the socket connections work there. If you can give me some pointers I'm happy to debug further.

NV-CONTROL extension

Hi, I'm the developer of GWE and I am currently trying to move from minx to python-xlib as library that implements the X Protocol.

Currently I am trying to create an NV-CONTROL extension extension myself but it would be helpful if we can cooperate since I am not familiar with the python-xlib nor the X Protocol in general.

I'm already able to request and read the reply of a simple integer value (GPU vram size):

from Xlib.protocol import rq

extname = 'NV-CONTROL'


class GetVram(rq.ReplyRequest):
    _request = rq.Struct(
        rq.Card8('opcode'),
        rq.Opcode(2),
        rq.Card16('m1'),
        rq.Card16('target_id'),
        rq.Card16('target_type'),
        rq.Card32('display_mask'),
        rq.Card32('attr'),
    )
    _reply = rq.Struct(
        rq.ReplyCode(),
        rq.Card8('pad0'),
        rq.Card16('sequence_number'),
        rq.ReplyLength(),
        rq.Card32('flags'),
        rq.Card32('value'),
        rq.Card32('pad4'),
        rq.Card32('pad5'),
        rq.Card32('pad6'),
        rq.Card32('pad7'),
    )


def get_vram(self):
    return GetVram(display=self.display,
                   opcode=156,
                   m1=4,
                   target_id=0,
                   target_type=1,
                   display_mask=0,
                   attr=6
                   )


def init(disp, info):
    disp.extension_add_method('display', 'nvcontrol_get_vram', get_vram)

(Just as a test I have hardcoded all the parameters)

Most of the NV-CONTROL protocol is already implemented for minx here.

Let me know if you can help me in creating this extension.

Unable to call SelectInput with `SubstructureRedirectMask | SubstructureNotifyMask` mask

Good day,
I was trying to port https://github.com/jichu4n/basic_wm to python using python-xlib, but getting failure while trying to use mask like SubstructureRedirectMask | SubstructureNotifyMask

I was using SelectInput request class provided by Xlib.ext.randr package. Here is the code snippet

from Xlib import rdb
from Xlib.X import SubstructureRedirectMask, SubstructureNotifyMask
from Xlib.protocol.display import Display
import os

from Xlib.error import BadAccess
from Xlib.ext.randr import SelectInput


class WindowManager(object):
    def __init__(self, display):
        self.display = display
        self.root = display.screen().root
        self.other_wm_detected = False

    def on_wm_detected(self, e):
        print('On wm detected %s' % e)
        assert e.error_code == BadAccess
        self.other_wm_detected = True


    def run(self):
        self.display.set_error_handler(self.on_wm_detected)
      
        SelectInput(
            display=self.display.display,
            opcode=self.display.display.get_extension_major('RANDR'),
            window=self.root.id,
            mask=SubstructureRedirectMask | SubstructureNotifyMask
        )
        self.display.sync()
        if self.other_wm_detected:
            raise ValueError('Detected another window manager on display %s' % self.display.display)



wm_options = rdb.stdopts.copy()
wm_options['-debug'] =  rdb.SepArg('.debug')
wm_options['-version'] =  rdb.IsArg('.version')

if __name__ == "__main__":
    address = "localhost:0.0"
    os.environ[ "DISPLAY" ] = address
    extra_options = {}
    opts = wm_options.copy()
    opts.update(extra_options)

    disp, name, db, args = rdb.get_display_opts(opts)
    wm = WindowManager(disp)
    wm.run()

Here is the stacktrace Iḿ getting

Traceback (most recent call last):
  File "/home/ekondrashev/sources/python/py-xlib/pywm.py", line 57, in <module>
    wm.run()
  File "/home/ekondrashev/sources/python/py-xlib/pywm.py", line 34, in run
    mask=SubstructureRedirectMask
  File "/home/ekondrashev/sources/python/py-xlib/venv3.5/lib/python3.5/site-packages/Xlib/protocol/rq.py", line 1350, in __init__
    self._binary = self._request.to_binary(*args, **keys)
  File "/home/ekondrashev/sources/python/py-xlib/venv3.5/lib/python3.5/site-packages/Xlib/protocol/rq.py", line 1070, in to_binary
    static_part = struct.pack(self.static_codes, *pack_items)
struct.error: ushort format requires 0 <= number <= (0x7fff * 2 + 1)

.tostring becoming deprecated in python3

So I have been running python-xlib for quite som time, and since my distribution upgraded to python3.6 i have gotten this message very often

/usr/lib/python3.6/site-packages/python_xlib-0.19-py3.6.egg/Xlib/protocol/rq.py:1012: DeprecationWarning: tostring() is deprecated. Use tobytes() instead.

So today i decided to fix it. Was an easy fix, here's the diff

diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py
index c945c62..11ea61c 100644
--- a/Xlib/protocol/rq.py
+++ b/Xlib/protocol/rq.py
@@ -553,7 +553,7 @@ class List(ValueField):
             if self.type.check_value is not None:
                 val = [self.type.check_value(v) for v in val]
             data = array(struct_to_array_codes[self.type.structcode],
-                               val).tostring()
+                               val).tobytes()
         else:
             data = []
             for v in val:
@@ -685,7 +685,7 @@ class PropertyData(ValueField):
                 val = list(val)
 
             size = fmt // 8
-            data = array(array_unsigned_codes[size], val).tostring()
+            data = array(array_unsigned_codes[size], val).tobytes()
             dlen = len(val)
 
         dl = len(data)
@@ -806,7 +806,7 @@ class KeyboardMapping(ValueField):
             for i in range(len(v), keycodes):
                 a.append(X.NoSymbol)
 
-        return a.tostring(), len(value), keycodes
+        return a.tobytes(), len(value), keycodes
 
 
 class ModifierMapping(ValueField):
@@ -837,7 +837,7 @@ class ModifierMapping(ValueField):
             for i in range(len(v), keycodes):
                 a.append(0)
 
-        return a.tostring(), len(value), keycodes
+        return a.tobytes(), len(value), keycodes
 
 class EventField(ValueField):
     structcode = None

So why did I did I not make a PR you might ask? Personally i only use python3 where the unit tests passed, but when i ran the unit tests under python2 things wasn't looking as good

54 failed, 463 passed, 406 skipped

I'm not really sure what to do about it, but atleast I'll create this issue so it won't be forgotten.

pypanel is no more working

With the release 0.16, pypanel is no more working. With 0.15rc1 and 0.14 it was perfect.
I'm running python2.7.

The panel appears, but like it was a picture. No possible interactions (click, minimize, ...)

By tracing the program, I see lot of calls to display.py , few to rq.py and lock.py. But no more calls to pypanel. Thus sounds to be a problem in py-xlib.

How to reproduce ?
Just install pypanel (python2 setup.py build and install) and run it.

Crash with sample code in python 3

Using this sample code:
http://rosettacode.org/wiki/Window_creation/X11#Xlib_2
works fine with released python 2 (strangely pip install Xlib is installing 0.21) but crashes with released python 3 (0.23)

Traceback (most recent call last):
  File "aa2.py", line 34, in <module>
    Window(display.Display(), "Hello, World!").loop()
  File "aa2.py", line 28, in loop
    self.window.draw_text(self.gc, 10, 50, self.msg)
  File "/home/gerard/.local/lib/python3.5/site-packages/Xlib/xobject/drawable.py", line 275, in draw_text
    items = [text])
  File "/home/gerard/.local/lib/python3.5/site-packages/Xlib/protocol/rq.py", line 1347, in __init__
    self._binary = self._request.to_binary(*args, **keys)
  File "/home/gerard/.local/lib/python3.5/site-packages/Xlib/protocol/rq.py", line 1021, in to_binary
    v, l, fm = f.pack_value(field_args[f.name])
  File "/home/gerard/.local/lib/python3.5/site-packages/Xlib/protocol/rq.py", line 1253, in pack_value
    data = data + struct.pack('>BL', 255, v)
struct.error: required argument is not an integer

at the crash point the 'v' variable holds 'hello, world' (a string)

with the following patch it works better in both Python 2.7 and 3.5.2


--- rq.py.sav	2018-11-29 08:46:01.385200262 +0100
+++ rq.py	2018-11-30 16:51:15.461981603 +0100
@@ -1221,7 +1221,7 @@
 
         for v in value:
             # Let values be simple strings, meaning a delta of 0
-            if type(v) is bytes:
+            if type(v) in (str, bytes):
                 v = (0, v)
 
             # A tuple, it should be (delta, string)
@@ -1230,19 +1230,19 @@
             if isinstance(v, (tuple, dict, DictWrapper)):
 
                 if isinstance(v, tuple):
-                    delta, str = v
+                    delta, mstr = v
                 else:
                     delta = v['delta']
-                    str = v['string']
+                    mstr = v['string']
 
-                while delta or str:
+                while delta or mstr:
                     args['delta'] = delta
-                    args['string'] = str[:254]
+                    args['string'] = mstr[:254]
 
                     data = data + self.string_textitem.to_binary(*(), **args)
 
                     delta = 0
-                    str = str[254:]
+                    mstr = mstr[254:]
 
             # Else an integer, i.e. a font change
             else:

if it's really necessary I can do a PR, but as this is my first (rough) contact with this project, I don't expect my patch to do the right thing.

X does not work on OS X EI Capitan

I tried a project which used python-xlib on OS X EI Capitan. And the bottom is backtraces.
And I have found some issue on stackexchange. It's seems not a
bug related to python-xlib, but the X11 on Mac os has changed the socket path from /tmp to /private/tmp. I tried to change host.startswith('/tmp/'): to host.startswith('/private/tmp/'):, and then
the backtraces go away.
I also saw a similar ticket http://sourceforge.net/p/python-xlib/bugs/27/ which claimed fixed. I am not sure its the same issue.
I am just adding an issue here in case others come across the same problem. Hope not to bother you.

File "/Users/declanqian/Dev/site-lisp/webkit/xutils.py", line 31, in get_xlib_display
    xlib_display =  display.Display()
  File "/usr/local/lib/python2.7/site-packages/Xlib/display.py", line 83, in __init__
    self.display = _BaseDisplay(display)
  File "/usr/local/lib/python2.7/site-packages/Xlib/display.py", line 65, in __init__
    apply(protocol.display.Display.__init__, (self, ) + args, keys)
  File "/usr/local/lib/python2.7/site-packages/Xlib/protocol/display.py", line 49, in __init__
    self.socket = connect.get_socket(name, host, displayno)
  File "/usr/local/lib/python2.7/site-packages/Xlib/support/connect.py", line 79, in get_socket
    return mod.get_socket(dname, host, dno)
  File "/usr/local/lib/python2.7/site-packages/Xlib/support/unix_connect.py", line 90, in get_socket
    raise error.DisplayConnectionError(dname, str(val))
Xlib.error.DisplayConnectionError: Can't connect to display 
"/private/tmp/com.apple.launchd.userNDyhts/org.macosforge.xquartz:0": 
[Errno 8] nodename nor servname provided, or not known

Bad display name, macOS

Hello,
I am running macOS Mojave and I am trying to use python-xlib. I am using version 0.25 of python-xlib.

Here is the traceback that I am getting:

python3 main.py
{'style': PosixPath('/Users/alex/.config/inkscape-shortcut-manager/styles'), 'object': PosixPath('/Users/alex/.config/inkscape-shortcut-manager/objects')}
Traceback (most recent call last):
  File "main.py", line 106, in <module>
    main()
  File "main.py", line 78, in main
    disp = Display()
  File "/usr/local/lib/python3.7/site-packages/Xlib/display.py", line 89, in __init__
    self.display = _BaseDisplay(display)
  File "/usr/local/lib/python3.7/site-packages/Xlib/display.py", line 71, in __init__
    protocol_display.Display.__init__(self, *args, **keys)
  File "/usr/local/lib/python3.7/site-packages/Xlib/protocol/display.py", line 84, in __init__
    name, protocol, host, displayno, screenno = connect.get_display(display)
  File "/usr/local/lib/python3.7/site-packages/Xlib/support/connect.py", line 73, in get_display
    return mod.get_display(display)
  File "/usr/local/lib/python3.7/site-packages/Xlib/support/unix_connect.py", line 76, in get_display
    raise error.DisplayNameError(display)
Xlib.error.DisplayNameError: Bad display name "/private/tmp/com.apple.launchd.kzHzmjnNw7/org.macosforge.xquartz:0"

It seems that the regex match that is being performed on the string "/private/tmp/com.apple.launchd.kzHzmjnNw7/org.macosforge.xquartz:0" is failing, but I have no idea what is wrong (I have no programming experience with python-xlib/xquartz). I would be grateful if someone could help me out!

Best,
Alex

Can't seem to detect any _NET_WM_STATE_DEMANDS_ATTENTION except on urxvt windows

Hi

I'm detecting _NET_WM_STATE_DEMANDS_ATTENTION in _NET_WM_STATE and it works fine if I make a bell character in a rxvt-uncode terminal for example. However if I set the flag on other windows it isn't detected, even though xprop sees it. So far I've tried it on a few web browsers and clementine.

self._CLIENT_LIST = dsp.intern_atom("_NET_CLIENT_LIST")
self._STATE = dsp.intern_atom("_NET_WM_STATE")
self._URGENT = dsp.intern_atom("_NET_WM_STATE_DEMANDS_ATTENTION")
tasks = root.get_full_property(self._CLIENT_LIST, Xatom.WINDOW).value

for task in list(tasks):
	obj = dsp.create_resource_object("window", task)

	try:
		props = obj.get_full_property(self._STATE, Xatom.ATOM)
		if props:
			if self.get_name(obj) == "Clementine":     
				print(props)
	except:
		continue

The above will output:

<<class 'Xlib.protocol.request.GetProperty'> serial = 95, data = {'sequence_number': 95, 'property_type': 4, 'bytes_after': 0, 'value': (32, array('I', [867]))}, error = None>

As you see it only has one property value: 867, but using xprop on it shows:

wmctrl -l:
0x02c00007  3 raven Clementine

xprop -id  0x02c00007 | grep -i atten
_NET_WM_STATE(ATOM) = _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_DEMANDS_ATTENTION

I've just updated to the latest python-xlib to see if it works better than my
old version but it still doesn't detect it.

python-xlib-0.23
libX11-1.6.4

Any ideas?

xcomposite

Hello

I want to be able to use xcomposite from python to capture windows using ffmpeg.

I will make use of XCompositeRedirectWindow and XCompositeNameWindowPixmap

Can python-xlib do this?

If it cannot then would using a wrapper for xcomposite I created using SWIG play nice with python-xlib?

Thanks,
Regards, Jake.

Edit
I noticed the composite extension for xlib so I should be just able to use that instead of having to use the wrapper.
https://github.com/python-xlib/python-xlib/blob/master/Xlib/ext/composite.py

My next question would be, how would I go about redirecting existing windows on a given display when given a window id?

Thanks

Edit

I can use create_resource_object and Xatom to accomplish this, thanks.

Enabling RandR events raises TypeError: ord() expected string of length 1, but int found

Using Python 3.6 and the xrandr.py example, upon a RandR event being received by the client, a TypeError is raised.

   File "/home/joseph/x11-client/venv/lib/python3.6/site-packages/Xlib/protocol/rq.py", line 1369, in __init__
     self.reply()
   File "/home/joseph/x11-client/venv/lib/python3.6/site-packages/Xlib/protocol/rq.py", line 1381, in reply
     self._display.send_and_recv(request = self._serial)
   File "/home/joseph/x11-client/venv/lib/python3.6/site-packages/Xlib/protocol/display.py", line 613, in send_and_recv
     gotreq = self.parse_response(request)
   File "/home/joseph/x11-client/venv/lib/python3.6/site-packages/Xlib/protocol/display.py", line 731, in parse_response
     self.parse_event_response(rtype)
   File "/home/joseph/x11-client/venv/lib/python3.6/site-packages/Xlib/protocol/display.py", line 826, in parse_event_response
     estruct = estruct[ord(self.data_recv[1])]
 TypeError: ord() expected string of length 1, but int found

Documentation for keycode_to_keysym?

I've checked your examples, specifically the record_demo.py. The keysym you get here simply passes 0 as the shift index, which is not correct, so the output is always the unshifted character (for example lowercase 'a' instead of 'A' or 'a' instead of 'ä'). I know why you have likely done this, because it's very hard to find documentation on how to actually calculate the shift index out of the event.detail field (possibly combined with other state).

So in hopes that someone does know, can you point me to a place where I could possibly learn more about on how to correctly determine the shift index? I've attempted this ages ago on my own, and came up with something more or less working here, which seems to work in all cases for my keyboard configuration (including Alt-Gr or "left alt" special xkb mappings), but this doesn't feel correct and I'm sure there are scenarios where this wouldn't just work.

An exception is thrown when no .Xauthority file exists

Traceback (most recent call last):
  File "/home/sandbox/pxl/lib/python3.5/site-packages/Xlib/xauth.py", line 45, in __init__
    raw = open(filename, 'rb').read()
FileNotFoundError: [Errno 2] No such file or directory: '/home/sandbox/.Xauthority'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sandbox/pxl/lib/python3.5/site-packages/Xlib/display.py", line 89, in __init__
    self.display = _BaseDisplay(display)
  File "/home/sandbox/pxl/lib/python3.5/site-packages/Xlib/display.py", line 71, in __init__
    protocol_display.Display.__init__(self, *args, **keys)
  File "/home/sandbox/pxl/lib/python3.5/site-packages/Xlib/protocol/display.py", line 68, in __init__
    name, host, displayno)
  File "/home/sandbox/pxl/lib/python3.5/site-packages/Xlib/support/connect.py", line 101, in get_auth
    return mod.get_auth(sock, dname, host, dno)
  File "/home/sandbox/pxl/lib/python3.5/site-packages/Xlib/support/unix_connect.py", line 117, in new_get_auth
    au = xauth.Xauthority()
  File "/home/sandbox/pxl/lib/python3.5/site-packages/Xlib/xauth.py", line 47, in __init__
    raise error.XauthError('~/.Xauthority: %s' % err)
Xlib.error.XauthError: ~/.Xauthority: [Errno 2] No such file or directory: '/home/sandbox/.Xauthority'

The above exception is thrown when there is no ~/.Xauthority file present. All non-python-xlib programs, such as xrandr, x11vnc and gvim, work fine.

Can you call XInitThreads with this library?

I'm trying to run PyOpenGL in a separate thread, but get the error from X:

[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.

-- could I make this call with this library?

setup.py installs to UNKNOWN-0.0.0

OS: Slackware64-14.2
python-2.7.14-x86_64-1_slack14.2
python3-3.6.4-x86_64-1_SBo

When building and isntalling python-xlib using setup.py with either python2 or python3 I found its being installed to paths like this.

usr/lib64/python2.7/site-packages/UNKNOWN-0.0.0-py2.7.egg-info/
usr/lib64/python2.7/site-packages/UNKNOWN-0.0.0-py2.7.egg-info/requires.txt
usr/lib64/python2.7/site-packages/UNKNOWN-0.0.0-py2.7.egg-info/PKG-INFO
usr/lib64/python2.7/site-packages/UNKNOWN-0.0.0-py2.7.egg-info/top_level.txt
usr/lib64/python2.7/site-packages/UNKNOWN-0.0.0-py2.7.egg-info/dependency_links.txt
usr/lib64/python2.7/site-packages/UNKNOWN-0.0.0-py2.7.egg-info/SOURCES.txt

As a consequence any other python modules that use python-xlib fail to find it.

I bisected this to the following commit.

22a8e1929ad58b8168bcf5d931e8f6067ebdec0a is the first bad commit
commit 22a8e1929ad58b8168bcf5d931e8f6067ebdec0a
Author: Benoit Pierre <[email protected]>
Date:   Mon Dec 4 17:46:50 2017 +0100

    fixup metadata
    
    - use `setup.cfg`
    - tweak `README.rst`
    - mark Python 3.6 as supported
    - convert `NEWS` to `CHANGELOG.md`
    - set long description to the contents of `README.rst`

:000000 100644 0000000000000000000000000000000000000000 a33f8fdb0da2c2ad8a11c6edf904f2fd48906584 A	CHANGELOG.md
:100644 000000 0483c58fae9d32ad70257841aa201512dd2218f4 0000000000000000000000000000000000000000 D	NEWS
:100644 100644 f145f3da37439f202b8014fdf1a64b6a616a3601 e28f80cf90aa4ae49610a368b3a1164f72c5aeb9 M	README.rst
:100644 100644 2a9acf13daa95e85642ea255d3e3bd1ef8252804 ba1f408a289b95dee0a5f76981d66d94d2beeecf M	setup.cfg
:100644 100644 b425618fc1c48a7d7102a0bde6a1da04ac1d89cc 9b4a47e2d2283996c0248fe066e6abba06c5b6d3 M	setup.py

22a8e19

More specifically this started when setup.cfg was being used instead of setup.py.

I can partially revert this commit to resolve the issues, but a better solution would be preferred.

diff --git a/setup.py b/setup.py
index b425618..9b4a47e 100644
--- a/setup.py
+++ b/setup.py
@@ -2,24 +2,10 @@
 
 from setuptools import setup
 
-import Xlib
-
 
 setup(
-    name='python-xlib',
-    version=Xlib.__version_string__,
-
-    description='Python X Library',
-    download_url='https://github.com/python-xlib/python-xlib/releases',
-    url='https://github.com/python-xlib/python-xlib',
-    license='LGPLv2+',
-
-    author='Peter Liljenberg',
-    author_email='[email protected]',
-
     install_requires=['six>=1.10.0'],
     setup_requires=['setuptools-scm'],
-
     packages=[
         'Xlib',
         'Xlib.ext',
@@ -28,22 +14,4 @@
         'Xlib.support',
         'Xlib.xobject'
     ],
-
-    keywords='xlib x11 x windows',
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Environment :: X11 Applications',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.3',
-        'Programming Language :: Python :: 3.4',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: Implementation :: CPython',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-        'Topic :: Software Development :: Libraries',
-        'Topic :: Software Development :: User Interfaces',
-    ],
 )

Another thing is that I can not reproduce this issue on Slackware current, but I'm puzzled what the difference is?

Cannot create display

As indicated in #71 , I used the linked stackoverflow code, provided below for convenience.

from Xlib import display, X
import PIL.Image #PIL, edited by PokestarFan to fix import

W,H = 200,200
dsp = display.Display()
root = dsp.screen().root
raw = root.get_image(0, 0, W,H, X.ZPixmap, 0xffffffff)
image = Image.fromstring("RGB", (W, H), raw.data, "raw", "BGRX")
image.show()

When I ran the code, I got the folowwing issue.

In [2]: from Xlib import display, X
   ...: from PIL import Image #PIL
   ...:
   ...: W,H = 200,200
   ...: dsp = display.Display()
   ...: root = dsp.screen().root
   ...: raw = root.get_image(0, 0, W,H, X.ZPixmap, 0xffffffff)
   ...: image = Image.fromstring("RGB", (W, H), raw.data, "raw", "BGRX")
   ...: image.show()
   ...:
   ...:
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-2-54cc7b666e0c> in <module>()
      3
      4 W,H = 200,200
----> 5 dsp = display.Display()
      6 root = dsp.screen().root
      7 raw = root.get_image(0, 0, W,H, X.ZPixmap, 0xffffffff)

c:\program files\python36\lib\site-packages\Xlib\display.py in __init__(self, display)
     87 class Display(object):
     88     def __init__(self, display = None):
---> 89         self.display = _BaseDisplay(display)
     90
     91         # Create the keymap cache

c:\program files\python36\lib\site-packages\Xlib\display.py in __init__(self, *args, **keys)
     69
     70     def __init__(self, *args, **keys):
---> 71         protocol_display.Display.__init__(self, *args, **keys)
     72         self._atom_cache = {}
     73

c:\program files\python36\lib\site-packages\Xlib\protocol\display.py in __init__(self, display)
     83
     84     def __init__(self, display = None):
---> 85         name, protocol, host, displayno, screenno = connect.get_display(display)
     86
     87         self.display_name = name

c:\program files\python36\lib\site-packages\Xlib\support\connect.py in get_display(display)
     70
     71     modname = _display_mods.get(platform, _default_display_mod)
---> 72     mod = _relative_import(modname)
     73     return mod.get_display(display)
     74

c:\program files\python36\lib\site-packages\Xlib\support\connect.py in _relative_import(modname)
     53
     54 def _relative_import(modname):
---> 55     return importlib.import_module('..' + modname, __name__)
     56
     57

c:\program files\python36\lib\importlib\__init__.py in import_module(name, package)
    124                 break
    125             level += 1
--> 126     return _bootstrap._gcd_import(name[level:], package, level)
    127
    128

c:\program files\python36\lib\importlib\_bootstrap.py in _gcd_import(name, package, level)

c:\program files\python36\lib\importlib\_bootstrap.py in _find_and_load(name, import_)

c:\program files\python36\lib\importlib\_bootstrap.py in _find_and_load_unlocked(name, import_)

c:\program files\python36\lib\importlib\_bootstrap.py in _load_unlocked(spec)

c:\program files\python36\lib\importlib\_bootstrap_external.py in exec_module(self, module)

c:\program files\python36\lib\importlib\_bootstrap.py in _call_with_frames_removed(f, *args, **kwds)

c:\program files\python36\lib\site-packages\Xlib\support\unix_connect.py in <module>()
     29 # in Python 2.2.
     30
---> 31 import fcntl
     32
     33 if hasattr(fcntl, 'F_SETFD'):

ModuleNotFoundError: No module named 'fcntl'

What is this fcntl module and why do i not have it?

I am on Windows 10 if that helps.

Grabbing a key does not stop propagation of event

As the title says. I'm not entirely clear on owner_events, but both True and False behave the same.
Tested on ubuntu 16.10.
It partially works on ubuntu 14.04, by partially I mean grabbing a modified key (e.g.<super><shift>p) works as expected, but grabbing a key without modifiers does not stop event propagation.

Tests fail on big-endian

On ppc64 I get lots of errors (after applying PR #75) like this:

ERROR: testUnpackReply0 (test.test_requests_be.TestAllocColor)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/test/test_requests_be.py", line 3829, in testUnpackReply0
    args, remain = request.AllocColor._reply.parse_binary(self.reply_bin_0, dummy_display, 1)
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/Xlib/protocol/rq.py", line 1146, in parse_binary
    val = struct.unpack(self.static_codes, data[:self.static_size])
TypeError: a bytes-like object is required, not 'str'

======================================================================
FAIL: testPackReply0 (test.test_requests_be.TestAllocColor)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/test/test_requests_be.py", line 3824, in testP
ackReply0
    assert bin == self.reply_bin_0
AssertionError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/test/test_requests_be.py", line 3826, in testP
ackReply0
    raise AssertionError(tohex(bin))
AssertionError: ["b'01002a9800000000ab080c6238bd0000'\n", "b'3fa738c8000000000000000000000000'\n"]

======================================================================
FAIL: testPackRequest0 (test.test_requests_be.TestAllocColor)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/test/test_requests_be.py", line 3806, in testPackRequest0
    assert bin == self.req_bin_0
AssertionError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/test/test_requests_be.py", line 3808, in testPackRequest0
    raise AssertionError(tohex(bin))
AssertionError: ["b'540000041f31c7dd9b2dc2bec1ac0000'\n"]

======================================================================
FAIL: testPackReply0 (test.test_requests_be.TestAllocColorCells)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/test/test_requests_be.py", line 3966, in testPackReply0
    assert bin == self.reply_bin_0
AssertionError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/fedora/rpmbuild/BUILD/python-xlib-0.19/test/test_requests_be.py", line 3968, in testPackReply0
    raise AssertionError(tohex(bin))
AssertionError: ["b'0100d309000000140011000300000000'\n", "b'00000000000000000000000000000000'\n", "b'294f7e294d2e493558235e3f6a369bd0'\n", "b'55f601676296189d2ef21d333e931239'\n", "b'69bc1c9c64ad40d260f35ed10a97f6cb'\n", "b'2766c36a7573969e7259c77b290a45d8'\n", "b'02724b732bbed7d53cfe7f342384b117'\n"]

though too many to list all.

Fails with unix display

This testcase

from Xlib.display import Display
display = Display()

fails when DISPLAY=unix:0.0

Traceback (most recent call last):
  File "testcase-xlib-problem.py", line 4, in <module>
    display = Display()
  File "/usr/local/lib/python2.7/site-packages/Xlib/display.py", line 89, in __init__
    self.display = _BaseDisplay(display)
  File "/usr/local/lib/python2.7/site-packages/Xlib/display.py", line 71, in __init__
    protocol_display.Display.__init__(self, *args, **keys)
  File "/usr/local/lib/python2.7/site-packages/Xlib/protocol/display.py", line 93, in __init__
    name, host, displayno)
  File "/usr/local/lib/python2.7/site-packages/Xlib/support/connect.py", line 102, in get_auth
    return mod.get_auth(sock, dname, host, dno)
  File "/usr/local/lib/python2.7/site-packages/Xlib/support/unix_connect.py", line 133, in new_get_auth
    addr = bytearray(int(x) for x in octets)
  File "/usr/local/lib/python2.7/site-packages/Xlib/support/unix_connect.py", line 133, in <genexpr>
    addr = bytearray(int(x) for x in octets)
ValueError: invalid literal for int() with base 10: '/'

Found on FreeBSD 11.1

`Window.get_wm_name` does not handle Unicode values

I'm using Python 3 and current PyPI version of Xlib.

When I call get_wm_name() on a window that has non-ASCII characters in the name, b'' is returned. I've traced this down as far as drawable.get_property and confirmed that the value returned from the request there is also b''.

display.py: KeyError: 'ge_add_event_data'

Hey guys, thanks for writing Xlib, it's been pretty useful to me recently :)

@kaushalmodi reported the following crash (original issue: nbedos/termtosvg#5). Is the caller of Xlib.display.Display expected to catch AttributeError, or is there something else going on here?

Thanks

km²~/.local/:bin> termtosvg                                                                                                                   06/28 1:18pm
Recording started, enter "exit" command or Control-D to end
Traceback (most recent call last):
  File "/home/kmodi/.local/lib/python3.7/site-packages/Xlib/display.py", line 224, in __getattr__
    function = self.display_extension_methods[attr]
KeyError: 'ge_add_event_data'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/kmodi/.local/bin/termtosvg", line 11, in <module>
    sys.exit(main())
  File "/home/kmodi/.local/lib/python3.7/site-packages/termtosvg/__main__.py", line 172, in main
    columns, lines, system_theme = term.get_configuration(output_fileno)
  File "/home/kmodi/.local/lib/python3.7/site-packages/termtosvg/term.py", line 340, in get_configuration
    xresources_str = _get_xresources()
  File "/home/kmodi/.local/lib/python3.7/site-packages/termtosvg/term.py", line 361, in _get_xresources
    d = display.Display()
  File "/home/kmodi/.local/lib/python3.7/site-packages/Xlib/display.py", line 127, in __init__
    mod.init(self, info)
  File "/home/kmodi/.local/lib/python3.7/site-packages/Xlib/ext/xinput.py", line 652, in init
    disp.ge_add_event_data(info.major_opcode, device_event, DeviceEventData)
  File "/home/kmodi/.local/lib/python3.7/site-packages/Xlib/display.py", line 227, in __getattr__
    raise AttributeError(attr)
AttributeError: ge_add_event_data

Deprecated method tostring() from Pillow/PIL breaks drawable.py

The tostring() method has been completely removed from the Pillow lib and replaced by tobytes().

When calling put_pil_image() (from Xlib/xobject/drawable.py) on line 244 the tostring() method is invoked and raises an error (ref: https://github.com/python-pillow/Pillow/blob/master/src/PIL/Image.py#L742 )

Out of curiosity I replaced that subimage.tostring by subimage.tobytes and it seems to work, but I haven't tested fully.

Encountered the issue by using this script where pixmap.put_pil_image(paint, 0, 0, im) crashes because of this bug. Hopefully this is the right place to report this. (I'm just a dumb user, sorry!)

Thanks for your time.

Update the python-xlib homepage.

The homepage does not mention anything about this github project. It maybe should as this seems to be the most active repository for python-xlib.

make html fails

Fedora Fedora Rawhide (28):

+ make html ps
(cd html; make)
make[1]: Entering directory '/builddir/build/BUILD/python-xlib-0.20/doc/html'
./texi2html -splitnode -menu ../src/python-xlib.texi
Unescaped left brace in regex is deprecated here (and will be fatal in Perl 5.30), passed through in regex; marked by <-- HERE in m/\@(\w+){ <-- HERE ([^\{\}]+)}/ at ./texi2html line 1805.
Unescaped left brace in regex is illegal here in regex; marked by <-- HERE in m/\@value{ <-- HERE ([^\s\{\}]+)}/ at ./texi2html line 860, <FH001> line 4.
make[1]: Leaving directory '/builddir/build/BUILD/python-xlib-0.20/doc/html'
make[1]: *** [Makefile:6: python-xlib_toc.html] Error 25
make: *** [Makefile:14: html] Error 2

BrokenPipeError not correctly handled

I get this error when using pynput (it completely crashes my X)

Exception in thread Thread-4481:
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/Xlib/protocol/display.py", line 584, in send_and_recv
    i = self.socket.send(self.data_send)
BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/site-packages/pynput/_util/__init__.py", line 136, in run
    self._run()
  File "/usr/lib/python3.7/site-packages/pynput/keyboard/_xorg.py", line 499, in _run
    super(Listener, self)._run()
  File "/usr/lib/python3.7/site-packages/pynput/_util/xorg.py", line 401, in _run
    self._suppress_stop(dm)
  File "/usr/lib/python3.7/contextlib.py", line 119, in __exit__
    next(self.gen)
  File "/usr/lib/python3.7/site-packages/pynput/_util/xorg.py", line 74, in display_manager
    display.sync()
  File "/usr/lib/python3.7/site-packages/Xlib/display.py", line 182, in sync
    self.get_pointer_control()
  File "/usr/lib/python3.7/site-packages/Xlib/display.py", line 833, in get_pointer_control
    return request.GetPointerControl(display = self.display)
  File "/usr/lib/python3.7/site-packages/Xlib/protocol/rq.py", line 1369, in __init__
    self.reply()
  File "/usr/lib/python3.7/site-packages/Xlib/protocol/rq.py", line 1381, in reply
    self._display.send_and_recv(request = self._serial)
  File "/usr/lib/python3.7/site-packages/Xlib/protocol/display.py", line 586, in send_and_recv
    self.close_internal('server: %s' % err[1])
TypeError: 'BrokenPipeError' object is not subscriptable

So the exception mightbe something from pynput or that I'm doing wrong,
but the exception following the exception seems to be in
/usr/lib/python3.7/site-packages/Xlib/protocol/display.py", line 586

xfixes selection notification

I have a little desktop utility written with the gtk clipboard helper that I'd like to convert to pure python with this library.

It notifies me of what the clipboard contents are and dynamically updates when the contents change. To do this, I need to be notified when the selection owner changes for the clipboard.

I found this article which says the way to do this is with XFixesSelectionNotify events. I need an implementation of XFixesSelectSelectionInput() for this.

When I get these events, I can convert the selection and get the clipboard contents from the owner window.

Would you accept a pull request to add this feature to the library?

xrandr_get_crtc_info trouble

I tried to use this nice library for something. Thank you for making it. However, even the xrandr example fails.

$git clone https://github.com/python-xlib/python-xlib.git
$cd python-xlib/examples
$python ./xrandr.py
... stuff ...
CRTC 635 info:
Traceback (most recent call last):
  File "./xrandr.py", line 196, in <module>
    Window(display.Display()).loop()
  File "./xrandr.py", line 133, in __init__
    self.pp.pprint(self.d.xrandr_get_crtc_info(crtc, resources['config_timestamp'])._data)
  File "/usr/lib/python2.7/dist-packages/Xlib/ext/randr.py", line 734, in get_crtc_info
    config_timestamp=config_timestamp,
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1478, in __init__
    self.reply()
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1490, in reply
    self._display.send_and_recv(request = self._serial)
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/display.py", line 556, in send_and_recv
    gotreq = self.parse_response(request)
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/display.py", line 643, in parse_response
    gotreq = self.parse_request_response(request) or gotreq
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/display.py", line 729, in parse_request_response
    req._parse_response(self.data_recv[:self.request_length])
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1502, in _parse_response
    self._data, d = self._reply.parse_binary(data, self._display, rawdict = 1)
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 1325, in parse_binary
    return self.parse_binary(data, display, rawdict)
  File "<string>", line 14, in parse_binary
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/rq.py", line 510, in parse_binary_value
    v = struct.unpack(scode, data[pos: pos + slen])
struct.error: unpack requires a string argument of length 4

The output of the regular xrandr is

Screen 0: minimum 8 x 8, current 3200 x 1200, maximum 16384 x 16384
DVI-I-0 connected 1280x1024+1920+88 (normal left inverted right x axis y axis) 337mm x 270mm
   1280x1024     60.02*+  75.02  
   1152x864      75.00  
   1024x768      75.03    70.07    60.00  
   800x600       75.00    72.19    60.32    56.25  
   640x480       75.00    72.81    59.94  
DVI-I-1 disconnected (normal left inverted right x axis y axis)
HDMI-0 disconnected (normal left inverted right x axis y axis)
DP-0 disconnected (normal left inverted right x axis y axis)
DVI-D-0 connected primary 1920x1200+0+0 (normal left inverted right x axis y axis) 519mm x 324mm
   1920x1200     59.95*+
   1680x1050     59.95  
   1600x1200     60.00  
   1280x1024     60.02  
   1280x960      60.00  
   1024x768      60.00  
   800x600       60.32  
   640x480       59.94  
DP-1 disconnected (normal left inverted right x axis y axis)

I have a dual monitor setup, obviously. My system is Mint Linux 18 (Ubuntu 16). Used python 2.7 for this test.

Question regarding KeyPress

When sending a KeyPress event with below code I would assume the key stays pressed until ... well ... forever. But all I get is a single "a".

`from Xlib import display,protocol,X,XK
import time

display = display.Display()
focus= display.get_input_focus()
window = focus.focus
keysym=XK.string_to_keysym("a")
keycode=display.keysym_to_keycode(keysym)
send_event = protocol.event.KeyPress(
time=int(time.time()),
root=display.screen().root,
window=window,
child=X.NONE,
same_screen=0,
root_x=0, root_y=0, event_x=0, event_y=0,
state=0,
detail=keycode
)
window.send_event(send_event)
display.sync()`

How to achieve a held down button?

Not getting events with next_event()

Reading of events such as mouse movement with Display.next_event() doesn't work for me. Is there anything recommended for debugging? Other functionality of python-xlib works. Getting the events with X11 command line tool as "xinput --test-xi2" also works fine as expected (prints events). This issue occurs both for the provided example file "examples/xinput.py" and a minimized version of it (see below).

Tested on Ubuntu 14.04 within a virtualenv with Python 2.7. I've tested with python-xlib release 0.17 installed via pip as well as current master branch from github.

Mimized snippet for reproducing:

from Xlib.display import Display
display = Display()
print "display:", display
print "version:", display.xinput_query_version()
print "pending events", display.pending_events()
print "now waiting for next event:", display.next_event()
print "done."

which prints:

display: <Xlib.display.Display object at 0x7fa417102910>
version: <<class 'Xlib.ext.xinput.XIQueryVersion'> serial = 13, data = {'major_version': 2, 'sequence_number': 13, 'minor_version': 0}, error = None>
pending events 0

and then hangs with the next_event() call despite mouse motion.

Any help or comments appreciated - thanks.

`send_and_recv` performance issue

bytes_recv = self.socket.recv(2048)

This simple program takes 10+ secs to run:

from Xlib import display, X

def main():
    win = display.Display().screen().root
    win.get_image(0, 0, 1280, 720, X.ZPixmap, 0xffffffff)

for i in range(10):
    main()

Consider using a large recv buffer as it will drastically increase performance. For example, if you use 2M instead of 2K buffer then the same program can have 20x speed boost.

Commit here: cykerway@a863c97

Python 3

Hello! I read the mailing list on SF. Is this going to support Python 3.3+ now? (3.3 is the real start of 3.x btw) If so, how can one help? What needs to be done?

python-xlib crashes app when $DISPLAY contains remote IP address

I discovered this issue when my mate-menu disappeared on remote terminals which forwarded their desktop across the network with simple X (not through SSH). After debugging a bit, I managed to find this.

user@compulab:~$ python -c 'from Xlib import display; d=display.Display()'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/Xlib/display.py", line 80, in __init__
    self.display = _BaseDisplay(display)
  File "/usr/lib/python2.7/dist-packages/Xlib/display.py", line 62, in __init__
    display.Display.__init__(*(self, ) + args, **keys)
  File "/usr/lib/python2.7/dist-packages/Xlib/protocol/display.py", line 61, in __init__
    name, host, displayno)
  File "/usr/lib/python2.7/dist-packages/Xlib/support/connect.py", line 93, in get_auth
    return getattr(mod, modname).get_auth(sock, dname, host, dno)
  File "/usr/lib/python2.7/dist-packages/Xlib/support/unix_connect.py", line 119, in new_get_auth
    return au.get_best_auth(family, addr, dno)
  File "/usr/lib/python2.7/dist-packages/Xlib/xauth.py", line 114, in get_best_auth
    address = address.encode()
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc0 in position 0: ordinal not in range(128)
user@compulab:~$ 

where the 0xc0 corresponds to the first set of the IP address, 192.

The issue can be isolated to python-xlib by the command
$ python -c 'from Xlib import display; d=display.Display()' from a remote display not over ssh.

Fix python2.7 -3 deprecation warnings

Current situation (initial import, commit d6a5a49):

$ (shopt -s globstar; for s in */**.py; do timeout 1 python2 -3 "$s"; done) 2>error.log
$ grep DeprecationWarning error.log | cut -f4- -d: | sort | uniq -c | sort -nr
    264  apply() not supported in 3.x; use func(*args, **kwargs)
    160  buffer() not supported in 3.x
     47  classic int division
     39  dict.has_key() not supported in 3.x; use the in operator
     24  The 'new' module has been removed in Python 3.0; use the 'types' module instead.
      5  CObject type is not supported in 3.x. Please use capsule objects instead.
      3  in 3.x, __getslice__ has been removed; use __getitem__

Every patch that lowers the number without causing regression is welcome :)

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

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

shape.ShapeInput not defined

I'm trying to set the input shape, with the Python equivalent of the C
XShapeCombineMask(dpy, win, ShapeInput, 0, 0, my_input_pm, ShapeSet);

I expected, based on the shapewin.py example, that would translate to something like
self.window.shape_mask(shape.ShapeUnion, shape.ShapeInput,
0, [something], self.my_input_pm)

But there's no shape.ShapeInput defined, and passing 2 (the definition of ShapeInput in <X11/extensions/shapeconst.h> raises ValueError: field region: argument 2 not in (0, 1).

Is there a way to set the input shape in Python? The C version works but I'd much rather use Python.

Event Handling is don't work

from Xlib import display
from Xlib import X
import time
disp = display.Display()
root = disp.screen().root
root.change_attributes(event_mask=X.KeymapStateMask) 
while 1:
    a = disp.next_event()
    print(a)
    time.sleep(1)

This code is don't catch the event of KeymapNotify

Results of testing examples

Examples have been tested on following OS: Ubuntu 14.04.4 LTS and Debian GNU/Linux 8 with KDE 5.

Python 2.7
Following examples run on both systems:
childwin.py,
eventthread.py,
get_selection.py,
put_selection.py,
profilex.py,
security.py,
shapewin.py,
threadtest.py,
xfixes.py,
xinerama.py,
xinput.py,
xlsatoms.py,
xrandr.py.

Following examples fall on both systems:
record_demo.py.

draw-proto.py and draw.py run on both systems, but on Debian changing window size causes such malfunction:
image

Python 3.4
All examples fall on both systems.

Bump to v0.24?

I maintain a package for this module for Buildroot, and my application depends on a change that was made after v0.23. Could we get a new release, so I can bump the Buildroot package?

Thanks!

RandR: get_screen_info() missing refresh rates [possible fix]

I've recently started using this library to get at structured RandR information. It's been really easy to jump in and start working with but couldn't find a way to get at the screen refresh rate information.

After a bit of searching around and reading up on XRandR I noticed that the xrandr_get_screen_info() function is what I was interested in but it looks like the refresh rates list is currently tagged with a FIXME.

I did a bit of debugging/reading and figured out that:

  • The refresh rate list was added in version 1.2 (?) (requires call to xrandr_query_version())
  • The sub-lists are not 32-bit aligned (requires removing padding to unpack correctly)

I was able to get it working with the below changes (admittedly I have not tested the code extensively but simply setting the pad argument to 0 appears to extract the list without breaking backwards compatibility).

diff --git a/Xlib/ext/randr.py b/Xlib/ext/randr.py
index 0a1dfb9..c15ec95 100644
--- a/Xlib/ext/randr.py
+++ b/Xlib/ext/randr.py
@@ -151,7 +151,7 @@ RandR_ModeInfo = rq.Struct(
 
 RandR_Rates = rq.Struct(
         rq.LengthOf('rates', 2),
-        rq.List('rates', rq.Card16Obj)
+        rq.List('rates', rq.Card16Obj, pad = 0)
         )
 
 # TODO: This struct is part of the RENDER extension and should be moved there
@@ -323,7 +323,7 @@ class GetScreenInfo(rq.ReplyRequest):
         rq.Card16('n_rate_ents'), # XCB's protocol description disagrees with the X headers on this; ignoring.
         rq.Pad(2),
         rq.List('sizes', RandR_ScreenSizes),
-        #rq.List('rates', RandR_Rates) #FIXME: Why does uncommenting this cause an error?
+        rq.List('rates', RandR_Rates)
         )
 
 def get_screen_info(self):

I am still very new to this code base, Xrandr and the X Server Protocol in general so I'm not sure if this could cause issues elsewhere. This method doesn't get the size of the refresh rate list ahead of time and I toyed with the idea of using either the length of the size list or n_rate_ents to compute the length but this feels cleaner and safer.

Hoping to get a second opinion or see if this fix might be considered.

Quick example of getting the rates from root screen (both with "initial" and latest version of Xrandr):

Python 3.7.3 (default, Mar 26 2019, 21:43:19) 
[GCC 8.2.1 20181127] on linux
Type "help", "copyright", "credits" or "license" for more information.
+>>> from Xlib import display
+>>> from Xlib.ext import randr
+>>> import pprint
+>>> d = display.Display()
+>>> d.screen().root.xrandr_get_screen_info().rates
[]
+>>> d.xrandr_query_version()
<<class 'Xlib.ext.randr.QueryVersion'> serial = 15, data = {'sequence_number': 15, 'major_version': 1, 'minor_version': 3}, error = None>
+>>> pprint.pprint([ r._data for r in d.screen().root.xrandr_get_screen_info().rates ])
[{'rates': [60]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60, 56]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60]},
 {'rates': [60, 59]},
 {'rates': [60, 59]},
 {'rates': []}]
+>>>

UnicodeDecodeError in Python 3

return data.decode(), b''

This line caused a decoding error when run with Python 3.6:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd4 in position 0: invalid continuation byte

I'm wondering whether data.decode() will ever work for values in range [128, 256).

data.decode('latin1') solves my issue. But I think there may be similar cases in other parts of the project.

Pull Request: #85

The default encoding in Python 3 is utf-8, which doesn't work in this case. ascii won't work, either.

Memory leak every new instance of Display()

I found this issue after I got a report that GWE was using 1.6 GB after several hours of execution (normally it should be around 100MB).

The problem seems to be that every time a new instance of display.Display() is created, a new type for all the resource classes is generated:

self.display.resource_classes[class_name] = type(origcls.__name__,

This is a problem if, like in GWE, you want to periodically use an extension and a new instance of Display is created and closed after each invocation.

A simple reproduction script can be found here:
https://github.com/leinardi/python-xlib/blob/memory-leak/leak.py

Top 1 lines
#1: <frozen importlib._bootstrap_external>:487: 398.2 KiB
1903 other: 984.7 KiB
Total allocated size: 1382.9 KiB
Top 1 lines
#1: Xlib/display.py:137: 600.6 KiB
    dictionary)
1956 other: 2485.5 KiB
Total allocated size: 3086.1 KiB
Top 1 lines
#1: Xlib/display.py:137: 1435.7 KiB
    dictionary)
1960 other: 3467.0 KiB
Total allocated size: 4902.7 KiB
Top 1 lines
#1: Xlib/display.py:137: 2505.5 KiB
    dictionary)
1961 other: 4612.2 KiB
Total allocated size: 7117.7 KiB
Top 1 lines
#1: Xlib/display.py:137: 3809.2 KiB
    dictionary)
1963 other: 3137.9 KiB
Total allocated size: 6947.1 KiB
Top 1 lines
#1: Xlib/display.py:137: 5347.5 KiB
    dictionary)
1963 other: 3597.0 KiB
Total allocated size: 8944.5 KiB

How to take a screenshot/screen capture of a specific window?

I'm looking for a way to capture screen shots/screen captures. I'm basically looking for the functionality offered by imagemagick's import tool. I went over the example code but didn't see anything that was capturing screen shots.
I was hoping someone could point me in the right direction. I'm assuming there might be a way using the display module?

Any help is greatly appreciated, thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.