Repository: psychopy/psychopy

Issue:
[Feature Request]: more flexible settings for measuring frame rate
### PsychoPy Version

2023.2.3

### What OS are your PsychoPy running on?

Linux-based systems

### Bug Description

Creating a window with `psychopy.visual.Window()` now displays the text "Attempting to measure frame rate of screen, please wait…" as part of its initialization. Previously, PsychoPy measured frame rate without displaying any text.

### Expected Behaviour

I think the new text is highly distracting, and I'd prefer to have a blank screen instead (just like in previous versions). 

### Steps to Reproduce

1. Create a new window with `psychopy.visual.Window()`
2. You'll see the text while frame rate is being measured.

### Additional context

This question has also come up in the forum: https://discourse.psychopy.org/t/is-there-a-way-to-skip-frame-rate-measurement-on-each-initialisation/36232/1


Discussion:
I have this issue, too, on MacOS Sonoma
This would be a good first issue for someone that wants to contribute. Ultimately we would like a new param in the psychopy/experiment/components/settings called `Check screen timing` that has these options:

1. with info message
2. with no info message
3. never

To achieve that (notably the (2) option) we also need to add an arg to `Window.getActualFrameRate`, something like `infoMsg="Attempting to measure frame rate of screen, please wait ..."`

I'd still consider this a bug, because the behavior changed suddenly, i.e. without prior notice. In addition, getting the previous behavior (no message) is impossible.

But anyway, I could implement this, at least the non-GUI part. I'd also argue for keeping the default behavior an empty message, because participants do not need to be confronted with the technical implementation details of a PsychoPy experiment. A blank screen for 1–2 seconds is much better than a confusing message, which has nothing to do with the experiment.
In software dev we consider a bug to be when something happens that was not the developers' intended behaviour. This was intended. It was also actually notified in advance, [in the changelog for 2023.2.0](https://github.com/psychopy/psychopy/releases/tag/2023.2.0) when it was introduced

Feel free to submit a PR for the parts you have knowledge about. We'll add the application control if that's not your thing.

We'll revisit, in the team, what to make the default and others can chime in here. 
I didn't see that, I apologize for saying that it was not announced.

Resolving patch:
diff --git a/psychopy/visual/window.py b/psychopy/visual/window.py
--- a/psychopy/visual/window.py
+++ b/psychopy/visual/window.py
@@ -189,7 +189,8 @@ def __init__(self,
                  bpc=(8, 8, 8),
                  depthBits=8,
                  stencilBits=8,
-                 backendConf=None):
+                 backendConf=None,
+                 infoMsg=None):
         """
         These attributes can only be set at initialization. See further down
         for a list of attributes which can be changed after initialization
@@ -242,7 +243,9 @@ def __init__(self,
             instead.
         checkTiming : bool
             Whether to calculate frame duration on initialization. Estimated
-            duration is saved in :py:attr:`~Window.monitorFramePeriod`.
+            duration is saved in :py:attr:`~Window.monitorFramePeriod`. The
+            message displayed on the screen can be set with the `infoMsg`
+            argument.
         allowStencil : bool
             When set to `True`, this allows operations that use the OpenGL
             stencil buffer (notably, allowing the
@@ -298,6 +301,11 @@ def __init__(self,
             available across all of them. This allows you to pass special
             configuration options to a specific backend to configure the
             feature.
+        infoMsg : str or None
+            Message to display during frame rate measurement (i.e., when
+            ``checkTiming=True``). Default is None, which means that a default
+            message is displayed. If you want to hide the message, pass an
+            empty string.
 
         Notes
         -----
@@ -616,7 +624,7 @@ def __init__(self,
         # for testing when to stop drawing a stim:
         self.monitorFramePeriod = 0.0
         if checkTiming:
-            self._monitorFrameRate = self.getActualFrameRate()
+            self._monitorFrameRate = self.getActualFrameRate(infoMsg=infoMsg)
 
         if self._monitorFrameRate is not None:
             self.monitorFramePeriod = 1.0 / self._monitorFrameRate
@@ -3312,7 +3320,7 @@ def hideMessage(self):
         self._showSplash = False
 
     def getActualFrameRate(self, nIdentical=10, nMaxFrames=100,
-                           nWarmUpFrames=10, threshold=1):
+                           nWarmUpFrames=10, threshold=1, infoMsg=None):
         """Measures the actual frames-per-second (FPS) for the screen.
 
         This is done by waiting (for a max of `nMaxFrames`) until
@@ -3350,8 +3358,10 @@ def getActualFrameRate(self, nIdentical=10, nMaxFrames=100,
         screen = self.screen
         name = self.name
 
-        self.showMessage(
-            "Attempting to measure frame rate of screen, please wait ...")
+        if infoMsg is None:
+            infoMsg = "Attempting to measure frame rate of screen, please wait ..."
+
+        self.showMessage(infoMsg)
 
         # log that we're measuring the frame rate now
         if self.autoLog:


Test patch: