Kalmat / PyWinCtl

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

Ubuntu - getAllWindows returns empty string titles #72

Closed cedricscheepers closed 12 months ago

cedricscheepers commented 1 year ago

This was still working in version 0.0.43 on Ubuntu.

If I call getAllWindows, I get a list ['', '', '', '', 'LXQt Panel']. If I call getAllAppsWindowsTitles, I get the dict {'pcmanfm-qt': [''], 'chrome': ['', ''], 'java': [''], 'lxqt-panel': ['LXQt Panel']}.

With the same windows open, rolling back to version 0.0.43, I get (for the same 2 functions mentioned above): ['pcmanfm-qt', 'PB Trust Admin | Home - Google Chrome', 'New Tab - Google Chrome', 'rpa ? requirements.txt', 'LXQt Panel'] {'pcmanfm-qt': ['pcmanfm-qt'], 'chrome': ['PB Trust Admin | Home - Google Chrome', 'New Tab - Google Chrome'], 'java': ['rpa ? requirements.txt'], 'lxqt-panel': ['LXQt Panel']}

I trust you will be able to fix this, as I love your library.

Kalmat commented 1 year ago

Hi! Thank you so much for your feedback!

Please, let me know some more details about your setup:

I have uploaded (not published on PyPi yet) a new version (v.0.1). I have tested both functions on my own Ubuntu (with GNOME/X11) and they are working OK in this last version. Can you please give it a try to check if this problem persists? You can download the wheel from here.

In the meantime I will download a copy of v0.0.43 to compare. I am not conscious of having modified those functions in particular, but clearly I did (somewhere else in the module, I guess).

Thank you again!

Kalmat commented 1 year ago

FOUND!!!

The problem was in the new ewmhlib module... Surprisingly, this doesn't work in all cases (like Chrome):

import pywinctl
import Xlib.display
display = Xlib.display.Display()

for win in pywinctl.getAllWindows():
    w = display.create_resource_object('window', win.getHandle())
    print(w.get_wm_name())   # In some cases this is EMPTY!!!

So I had to replace it by querying the property itself instead of using native Xlib function (partial code, not working):

ret: Optional[Xlib.protocol.request.GetProperty] = self.getProperty("_NET_WM_NAME")
res: Optional[Union[List[int], List[str]]] = getPropertyValue(ret)
if res:
        print(str(res[0]))

Thank you SO MUCH for finding and reporting it!!!

I will try to prepare an intermediate version (v0.0.51) fixing this issue, or perhaps I will try to finish all v0.1 tests to upload everything at once (are you in a hurry with this?)

EDIT I eventually decided to upload new v0.1 version to PyPi since the differences between v0.0.50 and v0.1 are slight, and all possible issues will likely be common, so I can solve them all at once when they arise. Please, give a try to new v0.1 version to check if everything is working OK in your case.

cedricscheepers commented 12 months ago

Thats great news! Glad you found it! Thank you for your really quick response, and even better finding a solution! Keep up the great work