flacjacket / pywayland

Python bindings for the libwayland library
Apache License 2.0
79 stars 16 forks source link

asyncio example ? #16

Closed sloonz closed 3 years ago

sloonz commented 3 years ago

The documentation states that Display.get_fd() can be used to integrate the client into the program event loop ; however I cannot make it work :

import asyncio    
from pywayland.client import Display    

class Client:    
    def __iniit__(self):    
        self.display = None    

    def wl_reader_ready(self):    
        print("ready")                                                   
        self.display.dispatch()     

    def create_display(self):                                            
        self.display = Display()                                         
        self.display.connect()                                           

        loop.add_reader(self.display.get_fd(), self.display.dispatch)    
        loop.call_later(5, self.use_wl_event_loop)                

        reg = self.display.get_registry()                         
        reg.dispatcher["global"] = self.handle_global             

    def handle_global(self, reg, id_num, iface_name, version):    
        print(id_num, iface_name)                 

    def use_wl_event_loop(self):                  
        print("falling back to wl event loop")    
        while True:                              
            self.display.dispatch(block=True)    

loop = asyncio.new_event_loop()            
loop.call_soon(Client().create_display)    
loop.run_forever()    

handle_global() callback is never called until the wayland event loop (as opposite to the wayland event loop) is called.

sloonz commented 3 years ago

This is working :

import asyncio    
from pywayland.client import Display    

display = Display()    
display.connect()    

loop = asyncio.new_event_loop()                                                                                                                    
loop.add_reader(display.get_fd(), lambda: display.dispatch(block=True))                                                                            

reg = display.get_registry()                                                                                                                       
reg.dispatcher["global"] = print    
display.flush()                     

loop.run_forever()                              

Two "traps" that are not obvious (at least for me !) and may be made more explicit somewhere (where ?) in the documentation :