Skip to content

MNT/FIX: macosx change Timer to NSTimer instance #26022

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

Merged
merged 3 commits into from
Jul 16, 2023

Conversation

greglucas
Copy link
Contributor

PR summary

Newer macos frameworks now support blocks, so we can take advantage of that and inline our method call while creating and scheduling the timer all at once. This removes some of the reference counting and alloc/dealloc record keeping.

In the mac framework, an interval of 0 will only fire once, so we need to account for that code path as well, which is easier with the repeat: option now. (See the first test block, which failed when interval=0 on the timer but we wanted it to keep firing)

PR checklist

src/_macosx.m Outdated
self->timer = NULL;
return (PyObject*) self;
}

static PyObject*
Timer_repr(Timer* self)
{
return PyUnicode_FromFormat("Timer object %p wrapping CFRunLoopTimerRef %p",
return PyUnicode_FromFormat("Timer object %p wrapping NSTimerRef %p",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NSTimer, not NSTimerRef?

@@ -44,3 +45,26 @@ def new_choose_save_file(title, directory, filename):
# Check the savefig.directory rcParam got updated because
# we added a subdirectory "test"
assert mpl.rcParams["savefig.directory"] == f"{tmp_path}/test"


@pytest.mark.backend('macosx')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the same test makes sense for other frameworks too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I just added it to test_backends_interactive instead. We'll see if all the other backends are also implemented properly ;)

@tacaswell tacaswell added this to the v3.8.0 milestone Jun 1, 2023
@greglucas
Copy link
Contributor Author

greglucas commented Jun 2, 2023

Well, what do you know Gtk doesn't like 0 for the interval and macosx didn't work with it before either, so I just pushed up a new commit setting a minimum of 1 millisecond for the interval of timers. This seems reasonable to me and I can't imagine anyone is counting on timers < 1/1000 of a second and they are entirely unreliable at that speed as well because we don't allow fractional numbers in the first place.


Edit: Seems like GtkCairo is the common failure point. We might need to increase the pause time and/or timer length to satisfy that backend.

@greglucas greglucas force-pushed the macosx-nstimer branch 2 times, most recently from de03aea to 8866eff Compare June 2, 2023 14:49
@anntzer
Copy link
Contributor

anntzer commented Jun 2, 2023

To be clear, I don't think you need to fix the other backends right now; xfailing them and opening an issue to track that is fine too.

@greglucas
Copy link
Contributor Author

To be clear, I don't think you need to fix the other backends right now; xfailing them and opening an issue to track that is fine too.

It does work locally for me on gtk3cario, so I think it must have something to do with the remote slowness which I just updated hoping it would work. If you don't want the minimum 1-millisecond commit then we would have to xfail.

However, luck would have it that either a new runner or QT release must have been put out within the last hour when I thought I had a fix up :) that is causing many more unrelated failures.

ImportError: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.35' not found (required by /opt/hostedtoolcache/Python/3.11.3/x64/lib/python3.11/site-packages/PyQt6/QtGui.abi3.so)

and

FAILED lib/matplotlib/tests/test_backend_qt.py::test_correct_key[Qt5Agg-alt_control] - DeprecationWarning: Enum value 'Qt::ApplicationAttribute.AA_EnableHighDpiScaling' is marked as deprecated, please check the documentation for more information.

@greglucas greglucas force-pushed the macosx-nstimer branch 2 times, most recently from 8b2bbac to 127d8ed Compare June 3, 2023 23:23
Newer macos frameworks now support blocks, so we can take advantage of
that and inline our method call while creating and scheduling the timer
all at once. This removes some of the reference counting and alloc/dealloc
record keeping.

In the mac framework, an interval of 0 will only fire once, so if we
aren't a singleshot timer we need to ensure that the interval is
greater than 0.
Some backends don't handle 0 interval timers, so we can just set
a minimum of 1 millisecond for the resolution of the timer to ensure
a positive interval passed to all backend timers.
@greglucas greglucas requested a review from anntzer June 22, 2023 15:17
Copy link
Member

@melissawm melissawm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a lot to say on the objective C stuff, but works fine on my intel mac.

@ksunden ksunden merged commit caa93d7 into matplotlib:main Jul 16, 2023
@greglucas greglucas deleted the macosx-nstimer branch July 16, 2023 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants