-
Notifications
You must be signed in to change notification settings - Fork 14
Method using gtk_application_inhibit() #407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
I have now a working implementation which still requires some refactoring + tests, but here are some timings. It can run in two modes:
TimingsHere are some timings for doing one inhibit -> uninhibit cycle: Code used for benchmarkingimport time
import logging
logging.basicConfig(level=logging.DEBUG)
from wakepy import keep
t0 = time.time()
with keep.presenting(methods=['gtk_application_inhibit']) as m:
...
t1 = time.time()
print(t1-t0)
Using local gi module:
Using the subprocess:
|
5ce3042
to
8c264f2
Compare
I'm leaving this one open. I'm working on other projects and I don't have this top of my priority list. Coming back to this later, whenever I have spare time for a new release :) |
1be37dd
to
d1eec70
Compare
Is the wakelock released if the main process crashes?There are two ways to crash a python process (1) With Exceptions, where normal context manager clean up takes place and TLDR:
Test 1: Normal ExceptionsUsing this script (foo.py) for testing the new "gtk_application_inhibit" method: import logging
import time
logging.basicConfig(level=logging.DEBUG)
from wakepy import keep
t0 = time.time()
with keep.presenting(methods=["gtk_application_inhibit"]) as m:
time.sleep(100)
time.sleep(10)
t1 = time.time()
print(t1 - t0) Running
And this is what I get when I place import logging
import time
logging.basicConfig(level=logging.DEBUG)
from wakepy import keep
t0 = time.time()
with keep.presenting(methods=["gtk_application_inhibit"]) as m:
time.sleep(40)
1 / 0
time.sleep(10)
t1 = time.time()
print(t1 - t0) the
The output in the terminal starting the foo.py:
In other words, if the script in the Test 2: SegfaultIt is also possible to crash a python process in a way which does not call the # foo.py
import ctypes
import logging
import time
logging.basicConfig(level=logging.DEBUG)
from wakepy import keep
with keep.presenting(methods=["gtk_application_inhibit"]) as m:
time.sleep(10)
ctypes.string_at(0) # This will cause a segmentation fault after 10 seconds
time.sleep(10) The
this is because the BrokenPipeError crashes the inhibitor server process. See:
|
d1eec70
to
c954020
Compare
License checkThe PyGObject (gi) is licensed under LGPLv2.1+. The LGPL permits linking (and importing) LGPL licensed code to code with any license, so there's no problem. In fact, if I understand it correctly, wakepy is just a “work that uses the Library”, and that work, in isolation, is not subject to the LGPL. In other words, importing (LGPL licensed) |
Unix sockets vs other alternativesThe alternatives for communicating between the main process (current env python) and sub-process (system python) are: subprocess.PIPE:
Unix sockets:
Message Queues
Communication through files:
ThoughtsThe only viable solutions seem to be unix sockets and subprocess.PIPE. The subprocess.PIPE is a bit more intriguing as it would be cross-platform solution. |
Closes: #404 #64
Add support for unix systems with GTK
PyGObject
(gi
) python library installed either on the current python environment or the system python site packages.Details
gi
, package name:PyGObject
) for inhibiting sleep/idle. This is the PyGObject interface to the gtk_application_inhibit() function.gi
module for accessing GTK functions from python. User is not required to have installed the PyGObject in their current (virtual) environment. It's just faster to use (300ms vs 5ms) ifgi
is available in the current python environment. Most people probably won't care if their long running script takes a 300ms more, and not having to install PyGObject is a nice thing as the installation will require compilation step(s), so it's a bit trickier and slower to install than a pure python package.Inhibitor
, which should comply with the new Inhibitor protocol: There must be astart(self, *args)
andstop(self)
methods. The*args
are positional arguments given to the server and passed to the inhibitor.TODO before merge
TODO Later
__file__
,import_module
, ..)