Kalmat / PyWinCtl

Cross-Platform module to get info on and control windows on screen
Other
179 stars 19 forks source link

Xlib.error.BadWindow on Manjaro Linux #90

Open Seraphli opened 2 months ago

Seraphli commented 2 months ago

I create a test script simply just run print(pwc.getAllTitles()) and get this error. Is this not working on Manjaro or Python 3.10.10?

Traceback (most recent call last):
  File "/home/seraphli/Workspace/Github/Seraphli/DBH/tmp1.py", line 6, in <module>
    print(pwc.getAllTitles())
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/pywinctl/_pywinctl_linux.py", line 129, in getAllTitles
    return [window.title for window in getAllWindows()]
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/pywinctl/_pywinctl_linux.py", line 129, in <listcomp>
    return [window.title for window in getAllWindows()]
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/pywinctl/_pywinctl_linux.py", line 812, in title
    name: Union[str, bytes] = self._win.getName()
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/ewmhlib/_ewmhlib.py", line 1095, in getName
    ret: Optional[Xlib.protocol.request.GetProperty] = self.getProperty(Window.NAME)
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/ewmhlib/_ewmhlib.py", line 1058, in getProperty
    return getProperty(self.xWindow, prop, prop_type, self.display)
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/ewmhlib/_ewmhlib.py", line 195, in getProperty
    return window.get_full_property(prop, prop_type)
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/Xlib/xobject/drawable.py", line 472, in get_full_property
    prop = self.get_property(property, property_type, 0, sizehint)
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/Xlib/xobject/drawable.py", line 455, in get_property
    r = request.GetProperty(display = self.display,
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/Xlib/protocol/rq.py", line 1368, in __init__
    self.reply()
  File "/home/seraphli/.pyenv/versions/dbh/lib/python3.10/site-packages/Xlib/protocol/rq.py", line 1388, in reply
    raise self._error
Xlib.error.BadWindow: <class 'Xlib.error.BadWindow'>: code = 3, resource_id = <Resource 0x00000000>, sequence_number = 41, major_opcode = 20, minor_opcode = 0
Seraphli commented 2 months ago

Currently a work around is using wins = pwc.getAllWindows() to get all windows and then try catch the Xlib.error.BadWindow exception.

Kalmat commented 2 months ago

Hi! Sorry for my late reply. Busy days!

First off, thank you for you feedback and help. Second, PyWinCtl is working fine in Manjaro. The only requirement is to use an EWMH-compliant Window/Desktop Manager, that I guess it is your case, right?

This error is very strange to me since getAllTitles() actually relies on getAllWindows() which is using a filter (__remove_bad_windows()) to catch BadWindow error amongst others:

def getAllTitles() -> List[str]:
    return [window.title for window in getAllWindows()]

def getAllWindows():
    if os.environ.get('XDG_SESSION_TYPE', '').lower() == "wayland":
        windowsList, _ = _WgetAllWindows()
        windows = [str(win["id"]) for win in windowsList]
    else:
        windows = defaultEwmhRoot.getClientListStacking()
    return __remove_bad_windows(windows)

def __remove_bad_windows(windows: Optional[Union[List[str], List[int]]]) -> List[LinuxWindow]:
    outList = []
    if windows is not None:
        for window in windows:
            try:
                outList.append(LinuxWindow(window))
            except:
                pass
    return outList

Do you have any idea about which kind of window may be producing the error? Or , perhaps, it is under certain conditions? Can you please provide more info about your specific case?

Thank you!!

Seraphli commented 2 months ago

I'm using Manjaro KDE Plasma. The error caused by a LinuxWindow(hWnd=0). I don't know why. Perhaps it's a permission problem? Or maybe there is a program without a window. image

Kalmat commented 1 month ago

Thank you!

If I am not wrong, hWnd=0 is typically associated to the root window, but your screenshot shows... two?!?!

Apart from that, this is really weird, since I specifically tested this new PyWinCtl version on an actual install of Manjaro/KDE, but this issue didn't arise in my tests.

Well, the solution in this case seems quite straight-forward, although we still don't know the real cause: modify the filter to also catch hWnd == 0, right?

Seraphli commented 1 month ago

but your screenshot shows... two?!?!

Yeah, I was also confused by this. It might be because I installed an input method on my Manjaro system. The settings bar of the input method appears on the desktop, but it doesn't show up in the window list. I'm not sure if this would be considered a window.

modify the filter to also catch hWnd == 0, right?

I guess so.