@@ -413,3 +413,89 @@ def _lazy_headless():
413
413
@pytest .mark .backend ('QtAgg' , skip_on_importerror = True )
414
414
def test_lazy_linux_headless ():
415
415
proc = _run_helper (_lazy_headless , timeout = _test_timeout , MPLBACKEND = "" )
416
+
417
+
418
+ def _test_number_of_draws_script ():
419
+ import matplotlib .pyplot as plt
420
+
421
+ fig , ax = plt .subplots ()
422
+
423
+ # animated=True tells matplotlib to only draw the artist when we
424
+ # explicitly request it
425
+ ln , = ax .plot ([0 , 1 ], [1 , 2 ], animated = True )
426
+
427
+ # make sure the window is raised, but the script keeps going
428
+ plt .show (block = False )
429
+ plt .pause (0.1 )
430
+ # Connect to draw_event to count the occurrences
431
+ fig .canvas .mpl_connect ('draw_event' , print )
432
+
433
+ # get copy of entire figure (everything inside fig.bbox)
434
+ # sans animated artist
435
+ bg = fig .canvas .copy_from_bbox (fig .bbox )
436
+ # draw the animated artist, this uses a cached renderer
437
+ ax .draw_artist (ln )
438
+ # show the result to the screen
439
+ fig .canvas .blit (fig .bbox )
440
+
441
+ for j in range (10 ):
442
+ # reset the background back in the canvas state, screen unchanged
443
+ fig .canvas .restore_region (bg )
444
+ # Create a **new** artist here, this is poor usage of blitting
445
+ # but good for testing to make sure that this doesn't create
446
+ # excessive draws
447
+ ln , = ax .plot ([0 , 1 ], [1 , 2 ])
448
+ # render the artist, updating the canvas state, but not the screen
449
+ ax .draw_artist (ln )
450
+ # copy the image to the GUI state, but screen might not changed yet
451
+ fig .canvas .blit (fig .bbox )
452
+ # flush any pending GUI events, re-painting the screen if needed
453
+ fig .canvas .flush_events ()
454
+
455
+ # Let the event loop process everything before leaving
456
+ plt .pause (0.1 )
457
+
458
+
459
+ _blit_backends = _get_testable_interactive_backends ()
460
+ for param in _blit_backends :
461
+ backend = param .values [0 ]["MPLBACKEND" ]
462
+ if backend == "gtk3cairo" :
463
+ # copy_from_bbox only works when rendering to an ImageSurface
464
+ param .marks .append (
465
+ pytest .mark .skip ("gtk3cairo does not support blitting" ))
466
+ elif backend == "wx" :
467
+ param .marks .append (
468
+ pytest .mark .skip ("wx does not support blitting" ))
469
+
470
+
471
+ @pytest .mark .parametrize ("env" , _blit_backends )
472
+ # subprocesses can struggle to get the display, so rerun a few times
473
+ @pytest .mark .flaky (reruns = 4 )
474
+ def test_blitting_events (env ):
475
+ # if env["MPLBACKEND"] == "macosx":
476
+ # if toolbar == "toolmanager":
477
+ # pytest.skip("toolmanager is not implemented for macosx.")
478
+ # proc = _run_helper(_test_interactive_impl,
479
+ # timeout=_test_timeout,
480
+ # **env)
481
+
482
+ # assert proc.stdout.count("CloseEvent") == 1
483
+
484
+ # proc = subprocess.run(
485
+ # [sys.executable, "-c",
486
+ # inspect.getsource(_test_number_of_draws_script)
487
+ # + "\n_test_number_of_draws_script()"],
488
+ # env={**os.environ, "SOURCE_DATE_EPOCH": "0", **env},
489
+ # timeout=_test_timeout,
490
+ # stdout=subprocess.PIPE, universal_newlines=True)
491
+
492
+ proc = _run_helper (_test_number_of_draws_script ,
493
+ timeout = _test_timeout ,
494
+ ** env )
495
+
496
+ # Count the number of draw_events we got. We could count some initial
497
+ # canvas draws (which vary in number by backend), but the critical
498
+ # check here is that it isn't 10 draws, which would be called if
499
+ # blitting is not properly implemented
500
+ ndraws = proc .stdout .count ("DrawEvent" )
501
+ assert 0 < ndraws < 5
0 commit comments