Kalmat / PyWinCtl

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

[BUG] Call too `getWmPid` in `getAppName` errors #43

Closed omlins closed 1 year ago

omlins commented 1 year ago

MWE:

import PySimpleGUI
import pywinctl

PySimpleGUI.popup('just say it!', 
        no_titlebar = False,
        keep_on_top = True,
        title = "dummy title",
        non_blocking = True,
        )

pywinctl.getAllAppsWindowsTitles()

Resulting error:

$ /bin/python3 /home/omlins/tmpwdir/juliadev/JustSayIt/src/gui_test2.py
Traceback (most recent call last):
  File "/home/omlins/tmpwdir/juliadev/JustSayIt/src/gui_test2.py", line 11, in <module>
    pywinctl.getAllAppsWindowsTitles()
  File "/home/omlins/.local/lib/python3.10/site-packages/pywinctl/_pywinctl_linux.py", line 235, in getAllAppsWindowsTitles
    appName = win.getAppName()
  File "/home/omlins/.local/lib/python3.10/site-packages/pywinctl/_pywinctl_linux.py", line 763, in getAppName
    pid = EWMH.getWmPid(self._hWnd)
  File "/home/omlins/.local/lib/python3.10/site-packages/ewmh/ewmh.py", line 400, in getWmPid
    return self._getProperty('_NET_WM_PID', win)[0]
TypeError: 'NoneType' object is not subscriptable

NOTE: The error occurred also when having a window open created with turtle. Thus, the problem does not only occur with PySimpleGUI, but probably with all GUIs that underneath rely on tkinter.

EWMH does not seem to be maintained very much anymore - maybe the exception can be avoided somehow...

MestreLion commented 1 year ago

Clearly an ewmh bug (not the first one...), but it's interesting the fix is already merged upstream https://github.com/parkouss/pyewmh/commit/acd586975622dd06fbb1c26e32bc0b1624daae59 . Actually this was the last PR (and commit) in ewmh before it died in 2017!

Of course, no new PyPi (or Github) release that includes the commit, so... it has to be patched here. Temporarily you can set pip to install the github "live" version instead of using a PyPi release

MestreLion commented 1 year ago
mestrelion@desktop ~/test $ pip install 'ewmh @ git+https://github.com/parkouss/pyewmh' PySimpleGUI pywinctl
Collecting ewmh@ git+https://github.com/parkouss/pyewmh
  Cloning https://github.com/parkouss/pyewmh to /tmp/pip-install-txl656b2/ewmh_877a7e50643f4bd0873c7df29ed2380f
  Running command git clone --filter=blob:none --quiet https://github.com/parkouss/pyewmh /tmp/pip-install-txl656b2/ewmh_877a7e50643f4bd0873c7df29ed2380f
  Resolved https://github.com/parkouss/pyewmh to commit 8209e9d942b4f39e32f14e2684d94bb5e6269aac
  Preparing metadata (setup.py) ... done
Collecting PySimpleGUI
  Using cached PySimpleGUI-4.60.4-py3-none-any.whl (509 kB)
...
Successfully built ewmh
Installing collected packages: PySimpleGUI, PyRect, six, xlib, python-xlib, ewmh, pywinctl
Successfully installed PyRect-0.2.0 PySimpleGUI-4.60.4 ewmh-0.1.6 python-xlib-0.33 pywinctl-0.0.42 six-1.16.0 xlib-0.21
mestrelion@desktop ~/test $ python
Python 3.8.0 (default, Dec  9 2021, 17:53:27) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import PySimpleGUI
>>> import pywinctl
>>> 
>>> PySimpleGUI.popup('just say it!', 
...         no_titlebar = False,
...         keep_on_top = True,
...         title = "dummy title",
...         non_blocking = True,
...         )
'__TIMEOUT__'
>>> 
>>> pywinctl.getAllAppsWindowsTitles()
error: process ID list syntax error

Usage:
 ps [options]

 Try 'ps --help <simple|list|output|threads|misc|all>'
  or 'ps --help <s|l|o|t|m|a>'
 for additional help text.

For more details see ps(1).
{'nautilus-deskto': ['Desktop'], 'gedit': ['*Untitled Document 2 - gedit'], 'firefox': ['[BUG] Call too `getWmPid` in `getAppName` errors · Issue #43 · Kalmat/PyWinCtl — Mozilla Firefox'], 'gnome-terminal-': ['Terminal'], '': ['dummy title'], 'compiz': [None, None, None, None, None]}
>>> 
MestreLion commented 1 year ago

The error now, I presume, is because PyWinCtl does not expect the now-fixed EWMH.getWmPid() to return None. But at least it does not explode :-)

Kalmat commented 1 year ago

Hi both! Thank you for your interest and time.

Following @MestreLion advice, I'm working in a new version which doesn't rely on ewmh anymore, using just Xlib. Major changes are already done, but it will take some time to check and test everything before I can upload a new release.

In the meantime, can you please uninstall pywinctl and install this wheel I am attaching? As I said, it's still work in progress, but it will really help me a lot if you can test it.

Besides, neither ewmh nor Xlib are working in my Ubuntu/GNOME 22.04 virtual machine. I hope it is because of Virtualbox or I am totally lost by the moment. I will physically install it on a separate partition within my PC to check (finger crossed).

PyWinCtl-0.0.43-py3-none-any.zip

MestreLion commented 1 year ago

Wow, you're ditching ewmh already? Sweeeet!!!

I was just creating a PR to fix this... but an "ewmh-free" PyWinCtl will be even better!

So... how about instead of v0.0.43 (that's a lot of zeros! ) you name it 1.0, or at least 0.1 ? PyWinCtl is pretty mature by now, specially being a fork of PyGetWindow. It's used in production (my bot, lol!), and any library that's stable enough to be used by someone else has the right to be 1.0 :-)

In the meantime... I was also thinking of creating a ewmh replacement myself. Hey, the original is only 432 lines of code, can't be that hard! And could use a saner API

MestreLion commented 1 year ago

With the fix:

>>> for k, v in pywinctl.getAllAppsWindowsTitles().items(): print(f"{k!r}: {v}")
... 
'nautilus-deskto': ['Desktop']
'gedit': ['*Untitled Document 2 - gedit']
'java': ['PyWinCtl – _pywinctl_linux.py']
'firefox': ['Network Graph · Kalmat/PyWinCtl — Mozilla Firefox']
'gnome-terminal-': ['Terminal']
'': ['dummy title']
'compiz': [None, None, None, None, None]
>>> 
Kalmat commented 1 year ago

So... how about instead of v0.0.43 (that's a lot of zeros! ) you name it 1.0, or at least 0.1 ? PyWinCtl is pretty mature by now, specially being a fork of PyGetWindow. It's used in production (my bot, lol!), and any library that's stable enough to be used by someone else has the right to be 1.0 :-)

HAHAHA! Not sure if it's stable and tested enough in all its extent yet. These issues and tests from other users and setups really help me a lot to improve the module. Nevertheless you're right, too many zeroes!!! Next version will be 0.1 until the module is mature enough to be 1.0 (if this ever happens).

In the meantime... I was also thinking of creating a ewmh replacement myself. Hey, the original is only 432 lines of code, can't be that hard! And could use a saner API

I would strongly encourage you to do it. I (and I guess many, many other users) would be very happy to have it!!! (I have only coded the functions required by pywinctl). I'm not a real Xlib expert, but I can help if you need/want it.

BTW, thank you for your fix! I can not commit anything until next month because I spent all my github quota trying to commit the new typed version (30+ failed commits, I wasn't kidding). I have to wait or deactivate the typing checks... it's really driving me crazy.

MestreLion commented 1 year ago

HAHAHA! Not sure if it's stable and tested enough in all its extent yet.

No library (or software, for that matter) will ever be.

Nevertheless you're right, too many zeroes!!! Next version will be 0.1 until the module is mature enough to be 1.0 (if this ever happens).

Great, 0.1 is already a nice improvement!

As for 1.0, don't be afraid when the time comes: it's published, it's usable (and used), and it works. It already qualifies for 1.0

I would strongly encourage you to do it. I (and I guess many, many other users) would be very happy to have it!!! (I have only coded the functions required by pywinctl). I'm not a real Xlib expert, but I can help if you need/want it.

I'll publish a prototype so you (and everyone) can give some feedback on the API. I'm not an expert either, in fact this is my first time dealing with Xlib (and man, what a pain!). But still... EWMH is a small spec, ewmh is a small lib, I'm sure I can manage :)

BTW, thank you for your fix! I can not commit anything until next month because I spent all my github quota trying to commit the new typed version (30+ failed commits, I wasn't kidding). I have to wait or deactivate the typing checks... it's really driving me crazy.

I never used Github checks, not sure how quota works. Is it by number or checks, number of commits or Time / CPU usage? Some ideas:

By the way, I noticed you merged my PR, thanks! I noticed the tests started fine when I pushed, so perhaps you were still below quota. Whew!

Kalmat commented 1 year ago

I'll publish a prototype so you (and everyone) can give some feedback on the API. I'm not an expert either, in fact this is my first time dealing with Xlib (and man, what a pain!). But still... EWMH is a small spec, ewmh is a small lib, I'm sure I can manage :)

I will be very pleased to give it a try. Just let me know when you have it ready.

I never used Github checks, not sure how quota works. Is it by number or checks, number of commits or Time / CPU usage? Some ideas:

  • Drop the mypy and pyright checks on all but one platform. They're static checkers, your code is not executed, so you only need a single platform. Leave the multi-platform checks for the actual library run tests.
  • Static checkers also don't usually need several python versions, just the latest.
  • If the quota is about Time / CPU usage, disable pyright when quota is low. At least on my system it downloads and sets up a ton of things on each run. It takes a huge time compared to mypy, for debatable gains (what's the advantage of running two distinct static checkers? Projects usually pick with a single one)

I think the quota is intended to limit the CPU time. About all the rest, I have no criteria, to be honest. I will give a try to all your suggestions. Thank you! BTW, the best solution would be to replicate the checks locally. I've been googling around, but found nothing which uses the same checks than github does (I managed to run the checks in my system, but the results were not the same)... Will keep on searching.

By the way, I noticed you merged my PR, thanks! I noticed the tests started fine when I pushed, so perhaps you were still below quota. Whew!

HAHAHAHA! I think this counts on YOUR quota!!! And right the opposite: Thank YOU!

omlins commented 1 year ago

Thanks for the immediate fix! @Kalmat : Thanks a lot for developing this package! In my search for something suitable ( for using in https://github.com/omlins/JustSayIt.jl) I haven't seen anything else of this kind, at least nothing portable across OSs. Thus, this development is really fundamental!

Kalmat commented 1 year ago

@omlins , thank you so much for your kind words. I do really appreciate it and means a moral boost! Still a lot of work to do, but so happy to hear it's useful!!!

MestreLion commented 1 year ago

In the meantime... I was also thinking of creating a ewmh replacement myself. Hey, the original is only 432 lines of code, can't be that hard! And could use a saner API

I would strongly encourage you to do it. I (and I guess many, many other users) would be very happy to have it!!! (I have only coded the functions required by pywinctl). I'm not a real Xlib expert, but I can help if you need/want it.

I'll publish a prototype so you (and everyone) can give some feedback on the API. I'm not an expert either, in fact this is my first time dealing with Xlib (and man, what a pain!). But still... EWMH is a small spec, ewmh is a small lib, I'm sure I can manage :)

I will be very pleased to give it a try. Just let me know when you have it ready.

As promised: ewmh-client

Only a few methods implemented, just to test the core get_property/set_property/send_message main methods. Feel free to open issues to comment on every API suggestion you might have!