PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.

Home Page:https://www.PySimpleGUI.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug] macOS: Sometimes PySimpleGUI windows are completely invisible!

EdwardChamberlain opened this issue · comments

commented

Type of Issue (Enhancement, Error, Bug, Question)

Bug


Operating System

macOS (12.3.1)

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

Python version: 3.10.4 (v3.10.4:9d38120e33, Mar 23 2022, 17:29:05) [Clang 13.0.0 (clang-1300.0.29.30)]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.60.0
PySimpleGUI filename: /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/PySimpleGUI/PySimpleGUI.py


Troubleshooting

These items may solve your problem. Please check those you've done by changing - [ ] to - [X]

  • Searched main docs for your problem www.PySimpleGUI.org
  • Looked for Demo Programs that are similar to your goal Demos.PySimpleGUI.org
  • If not tkinter - looked for Demo Programs for specific port
  • For non tkinter - Looked at readme for your specific port if not PySimpleGUI (Qt, WX, Remi)
  • Run your program outside of your debugger (from a command line)
  • Searched through Issues (open and closed) to see if already reported Issues.PySimpleGUI.org
  • Tried using the PySimpleGUI.py file on GitHub. Your problem may have already been fixed but not released

Detailed Description

Infrequently (maybe 1/3 times) when opening a PySimpleGUI program the window will not be rendered and will instead be completely invisible to the user. The window shows up in the dock, and can be made active and even previewed - but theres nothing there! No errors are shown in the terminal (as I believe the window is functioning correctly).

I have tried both M1 native and intel-emulation python builds and the same happens in both.

This issue prevents multi window programs from operating as even if the main window works correctly the popup / sub-window may not render correctly, leaving the user with just a view of the (now non functioning) main window.

Code To Duplicate

I have used the example program to emulate this:

import PySimpleGUI as sg

# Define the window's contents
layout = [[sg.Text("What's your name?")],
          [sg.Input(key='-INPUT-')],
          [sg.Text(size=(40,1), key='-OUTPUT-')],
          [sg.Button('Ok'), sg.Button('Quit')]]

# Create the window
window = sg.Window('Window Title', layout)

# Display and interact with the Window using an Event Loop
while True:
    event, values = window.read()
    # See if user wants to quit or window was closed
    if event == sg.WINDOW_CLOSED or event == 'Quit':
        break
    # Output a message to the window
    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying PySimpleGUI")

# Finish up by removing from the screen
window.close()

Screenshot, Sketch, or Drawing

video: https://imgur.com/a/N2BF2Nm
video of multi window program failing: https://imgur.com/a/bzLEOFY


Watcha Makin?

Financial planner!

Thanks much for reporting, and for those screenshots! Excellent issue reporting! A+++ for content alone.

Was there an upgrade to the Apple software recently? Did you notice this starting to happen in relation to any other changes on your system?

I assume, but perhaps incorrectly, that this is a rather recent development and not something you've seen happen in the past.... can you verify that you have had a stable PySimpleGUI environment for any length of time prior to this error?

commented

Was there an upgrade to the Apple software recently? Did you notice this starting to happen in relation to any other changes on your system?

This is really hard to answer - I cant say I have noticed this before (and I would like to think I would have noticed it!) but I have done very little PySimpleGUI work on macOS before this week (nearly all of my previous work was Windows based) and this is the first time developing on an M1 / ARM based Mac (rather than intel). I can breakout the old intel Mac to see if I can replicate this behaviour but it will be slightly convoluted as it will be a different OS version.

I would be hesitant to say I had a stable PySimpleGUI before now as this is a new laptop so nothing proven on it yet!

Was there an upgrade to the Apple software recently? Did you notice this starting to happen in relation to any other changes on your system?

This is really hard to answer - I cant say I have noticed this before (and I would like to think I would have noticed it!) but I have done very little PySimpleGUI work on macOS before this week (nearly all of my previous work was Windows based) and this is the first time developing on an M1 / ARM based Mac (rather than intel). I can breakout the old intel Mac to see if I can replicate this behaviour but it will be slightly convoluted as it will be a different OS version.

I would be hesitant to say I had a stable PySimpleGUI before now as this is a new laptop so nothing proven on it yet!

I ran this on my MacBook and a VM, and I'm unable to reproduce it on either.
I do not own a new M1 Mac, however.

I have the exact same issue! I asked for help on stackoverflow.

Having this same issue with popup windows, sometimes they will show up correctly, sometimes they are completely hidden. I have keep_on_top=True set as well.

New M1 Macbook.

Just so we're clear... or not clear....

So far, this problem has only happened on M1 computers?

I cannot replicate this issue on my Windows 11 PC, only on my M1 Mac.

commented

Running on my old system - an intel mac I cannot reproduce this issue, however, there are differences in version..

Python version: 3.9.0 (v3.9.0:9cf6752276, Oct 5 2020, 11:29:23)
[Clang 6.0 (clang-600.0.57)]
port: tkinter
tkinter version: 8.6.8
PySimpleGUI version: 4.38.0
PySimpleGUI filename: /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/PySimpleGUI/PySimpleGUI.py

macOS 11.5.2
Processor 2.2 GHz Quad-Core Intel Core i7
Graphics Intel Iris Pro 1536 MB

commented

Apologies to double comment here but the same intel system after updating both python and pysimplegui to match still will not reproduce ths issue.

Python version: 3.10.4 (v3.10.4:9d38120e33, Mar 23 2022, 17:29:05) [Clang 13.0.0 (clang-1300.0.29.30)]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.60.1
PySimpleGUI filename: /Users/Edward/Documents/GitHub/FinanceAnalysis/env/lib/python3.10/site-packages/PySimpleGUI/PySimpleGUI.py

Back to the M1 mac:
Perhaps even more bizzarely I find that I can actually interact with the window that is invisible - If I can remember where the window will appear and where the buttons are (close for example) I can click that empty space on the screen and it will function correctly. It seems the window is there, both in function and in the window manager, but just isnt visible.

It seems the window is there, both in function and in the window manager, but just isnt visible.

image

This is a very important clue!

That means it's alpha channel related, at least in terms of an explanation of the state of the program.

[ Edit ] - Geez @EdwardChamberlain you've got nothing to apologize about!

If this is an easy test for someone to run, can someone try using a very old version of PySimpleGUI just to make sure nothing's been added recently that could contribute?

Maybe try something like 4.30.0 from Oct 2020?

image

image

Same issue.
Screen Shot 2022-06-01 at 9 53 44 AM

Video below:
https://user-images.githubusercontent.com/8294014/171461032-b67bd31e-0ad0-44f9-8ad9-eefa56d8651c.mov

Code below:

import PySimpleGUI as sg

layout = [
    [
        sg.Button("Test Button", key="Test"),
    ],
]

window = sg.Window(
    "Test",
    layout,
    finalize=True,
    font="Any 16",
)  # Define the window to be shown with the above objects

while True:

    # Read in the window events and values of the objects
    event, values = window.read()
    match event:
        case "Test":
             sg.popup(
                "This is a test popup!",
                keep_on_top=True,
                location=(1700, 1100),
            )
        case sg.WIN_CLOSED:
            break
        case "Close":
            break

window.close()
commented

Just beat me to it! Same issue on 4.30.0 and macOS: 12.3.1

(I see sg.main_get_debug_data() was added after 4.30.0!)

Just a though - it would be nice to be able to test similar macOS versions since my intel Mac is running 11.5.2 vs 12.3.1 on my M1. The intel Mac is too old to update, the M1 too new to downgrade. If someone has an intel Mac that can run 12.3.1 that might help close out that major macOS update as the cause.

commented

I have the exact same issue!

@geekzsp can tell us your version of tkinter? You can type psgver from the command line to get a window with the versions

@EdwardChamberlain The get_versions function now has the platform specific information. That function is called by main_get_debug_data and is shown in the window created when clicking the "Versions for GitHub" button from the Test Harness.

Here's how it appears on Windows:
image

commented

@PySimpleGUI Here is the output:

Python version: 3.10.4 (v3.10.4:9d38120e33, Mar 23 2022, 17:29:05) [Clang 13.0.0 (clang-1300.0.29.30)]
        port: tkinter
        tkinter version: 8.6.12
        PySimpleGUI version: 4.60.1
        PySimpleGUI filename: /Users/edward/Documents/Github/PySimpleGUI-3D-Viewer/env/lib/python3.10/site-packages/PySimpleGUI/PySimpleGUI.py

Curiously I haven't noticed this issue on the teapot project, and cant seem to replicate it using fresh code. (maybe it just hasn't showed up yet?). But running the older project it shows up almost immediately:

Odd2.mov

Perhaps the complexity / elements of the GUI have an affect on this issue?

Both of the GUIs in the clip above are running the version above and are (for this testing) being run from the same venv.

I have the exact same issue on a MacBook M1 Pro. It happens most often with the popup window. Maybe like every third time. As I can’t close the invisible window I have set it to close automatically after 3 seconds as a workaround. Quite annoying though.

@thebestben can you verify your versions? psgver will give you the data that you can post here that will be of great help. Thanks for commenting and adding to the pool of data!

I have a test to propose...

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, finalize=True)
window.set_alpha(1.0)
while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()

This program you can run and press enter to close the window.

It adds a statement after the window is created that sets the Alpha channel to 1 for the window.

The symptom I'm reading here and was confirmed by the help you this wonderful group of helpful users is that the window acts like the Alpha is simply 0.

When it doesn't show up, I'm curious if pressing enter still prints the "exiting" message.

Also curious if adding another Alpha Channel set to 1.0 "fixes" it.

commented

@PySimpleGUI Running the code I can reproduce the issue and the "exiting" is printed:

Go {'-IN-': ''}
exiting

Seems the window is fully functional!

commented

One thing probably worth noting is the regularity of this issue - with your code above im seeing this maybe 1 in 20 times I open the window. With my code (multi window) I am seeing this issue maybe 4 in 5 times. Im not sure what that means.

I updated your code to alter the 'go' event:

    if event == 'Go':
        print('setting window alpha')
        window.set_alpha(1.0)

When the window shows up as invisible pressing return does not reveal the window.

The theory was that the statement prior to the event loop:

window.set_alpha(1.0)

Would make the window appear.

If you want to use that "Go" button, you likely want a delay before exiting.

Also, let's try making the initial window slightly dim.

import PySimpleGUI as sg
import time

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=0.9, finalize=True)
while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        window.set_alpha(1.0)
        window.refresh()
        print('exiting')
        time.sleep(1)
        break

window.close()
commented

alpha_channel=0.9 is very odd! Running your exact code above I am completely unable to replicate the issue. Removing alpha_channel=0.9 the issue returns.

It seems that setting alpha_channel=0.99 creates a window that appears opaque but does not have the issue with occasional complete invisibility.

@EdwardChamberlain I love ya man! image

Nice! Thank you for doing all these tests this morning.

Can you set it to 1.1 instead of 0.99?

In other words, does this test work?

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=1.1)

while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()
commented

Code above (with alpha = 1.1) runs but produces the invisibility error.

Fascinating!

To be clear, the same code, with a value of 0.99 works?

commented

Copy paste of above!

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=1.1)

while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()

^ does not work.

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=0.99)

while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()

^ does work!

Question / test....

Does this produce a window every time that is not translucent?

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=0.99, finalize=True)

window.set_alpha(1.0)

while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()
commented

It seems to yes.

image

Huge victory!

Way to go Edward! We have a "workaround".... setting this one parameter and including this one statement "fixes" the problem. It's a patch that works. While it would be ideal to get the tkinter code fixed, at least we now have a way to get around the problem! Thank you SO much for this help! You're a hero today @EdwardChamberlain .

I'm sorry for brining bad news to the party, however, running this code:

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=0.99, finalize=True)

window.set_alpha(1.0)

while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()

I've got an invisible window with the second try :(
You can see my versions here

I'm sorry for brining bad news to the party>?

No sorry needed 😀 It's just part of debugging. I appreciate the help. All data, is good data.

commented

@Lu-Kali Hmm! Thats odd. I tried running the code you just posted 50 times and a window appeared every time!

@EdwardChamberlain I will run it a couple times and tell you my results.
Not showing after 14 runs... not showing after 40 runs... 3, 9, 2, 2, 2, 43

I'm using two monitors btw – I hope this helps

It is also happening (invisible windows) with popup windows to which I can't add alpha_channel or pass the set_alpha() method to test the workaround.

@thebestben can you verify your versions? psgver will give you the data that you can post here that will be of great help. Thanks for commenting and adding to the pool of data!

Python version: 3.10.1 (v3.10.1:2cd268a3a9, Dec 6 2021, 14:28:59) [Clang 13.0.0 (clang-1300.0.29.3)]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.60.1
PySimpleGUI filename: /Users/benbuller/Documents/Application Data/Python/DrinkShop5/venv/lib/python3.10/site-packages/PySimpleGUI/PySimpleGUI.py

I'm having the same problem on my M1 Macbook Pro. My main application window opens about 99% of the time (but very infrequently also comes up invisible. My sub-window popups and child windows come up very rarely if at all now.

I've run the test code above, but at least for about 10 iterations I got the window to come up ok with .99 or 1.0, however.

Python version: 3.9.12 (main, Jun 1 2022, 06:34:44)
[Clang 12.0.0 ]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.60.1

Isn't debugging intermittent problems so much fun?

image

It's a lot easier, a lot more enjoyable, a lot more productive with so much help and data coming in. I really appreciate so many of you jumping in.

@Chr0nicT is still waiting on his M1. He's tenacious as they get with bugs and I'm highly confident in his ability to get a resolution to this.

I had an idea that may make testing many iterations easier and that is to use the autoclose feature.

This program makes windows and closes them every second. You can "stop the madness" by clicking "stop" or you and exit the program by clicking "exit". You'll still have to watch what's happening, but it seems like it would be easier than a manual process.

If 1 second is too short, you can lengthen the autoclose time when making the window.

May be of help...

image

maybe not...

Again, thank you all so very much. We'll get this one nailed, I've no doubt about it. I can't recall so many people helping a Mac issue before. It's really awesome.

import PySimpleGUI as sg

window_count = 0

def make_window():
    global window_count
    layout = [  [sg.Text(f'Window Count = {window_count}', font='_ 16')],
                [sg.Input(key='-IN-')],
                [sg.Output(size=(60,10))],
                [sg.Button('Stop'), sg.Button('Version'), sg.Button('Exit')]  ]

    window = sg.Window('Window Title', layout, auto_close=True, auto_close_duration=1, finalize=True)

    window_count += 1
    return window


def main():
    window = make_window()
    while True:
        event, values = window.read()
        print(event, values)
        if event == sg.WIN_CLOSED:
            window = make_window()
        if event == 'Exit':
            window.close()
            break
        if event == 'Stop':
            sg.popup(f'Stopping at count', window_count)

if __name__ == '__main__':
    main()

@PySimpleGUI we thank you for your dedication with this topic! <3

That's a good test program!

I quickly tested and 10 out of 40 windows failed to appear on my M1, so it seems that program is a reasonable way to reproduce that error "at scale" for future testing.

Actually, it would be handy to have a "Log Failure" button of some kind, so that instead of mentally trying to keep track, you could click a button to increment the failure count (presumably on the next window that works) so it can spit out overall stats at the end for you.

I only thought about it and dashed it out in a 5 minute period.

Here's another one to try. I combined the color picker demo to check for a pixel that should be RED if the window is present, in theory.

import PySimpleGUI as sg
import PIL.ImageGrab

window_count = 0
CLOSE_TIME = 2000
def make_window():
    global window_count
    sg.theme_background_color('red')
    sg.theme_text_element_background_color('red')
    layout = [  [sg.Text(f'Window Count = {window_count}', font='_ 16')],
                [sg.T('X'), sg.Input(40, key='-X-',s=5), sg.T('Y'), sg.Input(40, key='-Y-', s=5)],
                # [sg.Output(size=(60,10))],
                [sg.Button('Stop'), sg.Button('Exit')]  ]

    window = sg.Window('Window Title', layout,  finalize=True)
    # window = sg.Window('Window Title', layout,finalize=True)

    window_count += 1
    return window
def main():


    window = make_window()
    while True:
        # event, values = window.read()
        event, values = window.read(timeout=CLOSE_TIME)
        print(event, values)
        if event == sg.WIN_CLOSED:
            window = make_window()
        if event == 'Exit':
            window.close()
            break
        if event == 'Stop':
            sg.popup(f'Stopping at count', window_count)
        if event == sg.TIMEOUT_EVENT:
        # if event == 'Get Color':
            x, y = window.current_location()
            x, y = x+int(values['-X-']), y+int(values['-Y-'])
            rgb = PIL.ImageGrab.grab().load()[x, y]
            hex_color = sg.rgb(*rgb)
            if hex_color != '#ff0000':
                sg.popup_error('No window error!', f'found color {hex_color}', keep_on_top=True)
            print(hex_color)
            window.close()
            window=make_window()
if __name__ == '__main__':
    main()

Here is how the auto-test ran on my system. I clicked the window that's behind the test window so that when the check for a ted pixel instead found the window I clicked.
brave_mK7HY83cfs

commented

Running a slightly modified version of your script:

TOTALS:
TOTAL WINDOWS: 200
 GOOD WINDOWS: 173
  BAD WINDOWS: 27

With the 0.99 alpha workaround:

TOTALS:
TOTAL WINDOWS: 200
 GOOD WINDOWS: 200
  BAD WINDOWS: 0

Removing the workaround again:

TOTALS:
TOTAL WINDOWS: 200
 GOOD WINDOWS: 181
  BAD WINDOWS: 19

Script:

import PySimpleGUI as sg
import PIL.ImageGrab
import time

# import workarounds

sg.theme_background_color('red')
sg.theme_text_element_background_color('red')

GOOD_WINDOWS = 0
BAD_WINDOWS = 0
CLOSE_TIME = 100
PAUSE_TIME = 0.1
TOTAL_WINDOWS = 200

for i in range(TOTAL_WINDOWS):
    print("Pausing...")
    time.sleep(PAUSE_TIME)

    layout = [
        [sg.Text(f'Window Count = {i}', font='_ 16')],
        [sg.Text(f"Good: {GOOD_WINDOWS} :: Bad: {BAD_WINDOWS}")],
    ]

    window = sg.Window('Window Title', layout, keep_on_top=True)

    print("Running Window...")
    while True:
        event, values = window.read(timeout=CLOSE_TIME)

        if sg.TIMEOUT_EVENT:
            print("Timeout event...")

            x, y = window.current_location()
            x, y = x+8, y+30
            x, y = x * 2, y * 2  # macOS uses a 2x scaling...
            x, y = 1363, 992  # Hardcoded to my screen

            screenshot = PIL.ImageGrab.grab()
            # screenshot.show()
            rgb = screenshot.load()
            pixel = rgb[x, y]
            pixel = pixel[:3]
            hex_color = sg.rgb(*pixel)

            print(hex_color)
            if hex_color != '#ea3323': # Two colour checks as the change in alpha adjusts colour slightly.
            # if hex_color != '#e83323':
                print("BAD WINDOW")
                BAD_WINDOWS += 1
            else:
                print("GOOD WINDOW")
                GOOD_WINDOWS += 1
                
            print("Window closing...")
            window.close()
            break
    print()
    print()

print(f"TOTALS:\nTOTAL WINDOWS: {TOTAL_WINDOWS}\n GOOD WINDOWS: {GOOD_WINDOWS}\n  BAD WINDOWS: {BAD_WINDOWS}")

For reference the workarounds.py script looks like this:

import functools
import PySimpleGUI as sg

# Thsi prevents an issue on macOS when using night mode where disabled input fields are rendered with black text on a black background.
uInput = functools.partial(
    sg.Input,
    disabled_readonly_background_color='white',
    disabled_readonly_text_color='black'
)
sg.Input = uInput

# This prevents an issue on macOS where the window is rendered transparent.
uWindow = functools.partial(
    sg.Window,
    alpha_channel=0.99,
)
sg.Window = uWindow

edit: re-run of the workaround:

TOTALS:
TOTAL WINDOWS: 500
 GOOD WINDOWS: 500
  BAD WINDOWS: 0

Oooooooooooooooooooooooooooooooooooooooooooooooooooooooo

VERY tasty code @EdwardChamberlain !
image

Love it!

Without alpha_channel=0.99

TOTALS:
TOTAL WINDOWS: 200
 GOOD WINDOWS: 114
  BAD WINDOWS: 86

With alpha_channel=0.99

TOTALS:
TOTAL WINDOWS: 200
 GOOD WINDOWS: 200
  BAD WINDOWS: 0

this time it seemed to fixed it... the last time with another program it didn't fix it...

hm.. that's strange. I ran the same code I've posted previously but this time the workaround worked and I could see every window...

EDIT
after posting this comment I tried again and it failed with the second execution! Maybe I didn't execute it enough

NEXT EDIT
now it behaves similar to here

ANOTHER EDIT
running Edward's code with the fix it worked for 200 rounds...

Well, I'm stupid... there was another set_alpha in the code and I oversaw that...

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=0.99, finalize=True)

window.set_alpha(1.0) #<–––––––––––––––––––––––––––HERE!

while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()

setting this also to 0.99 fixed it. So I can finally confirm that 0.99 is a working workaround for normal windows but what about popups?

There's no alpha channel setting for popups :(

My result with @EdwardChamberlain s code.

TOTAL WINDOWS: 200
GOOD WINDOWS: 144
BAD WINDOWS: 56

commented

@thebestben Hi Ben - are you running my code here exactly as I posted it? (with the workarounds commented out)

If so then this is the "expected" result. Are you able to run it again with the workarounds.py imported (and you will need to switch the if statement to whatever colour is shown on a good window as the opacity will pick up a small amount of colour from the window behind)

I would like to find a way to get the alpha back to 1.0 once the window is visible. Perhaps sleeping a short period before trying to set the alpha? Or refreshing the window? We've not tried many things to go from 0.99 back again.

@ZSamuels28 you're right that no alpha is available on popups at this point. The good news is that you can make a popup in a single line of PySimpleGUI code. Making a popup using your own layout is not difficult once you learn to make a window.

Using tkinter, it looks like their windows popup everytime

from tkinter import *
from tkinter import ttk

# Create an instance of Tkinter frame
win = Tk()
# Set the geometry of Tkinter frame


def open_popup():
    top = Toplevel(win)
    top.geometry("750x250")
    top.title("Child Window")
    Label(top, text="Hello World!", font=("Mistral 18 bold")).place(x=150, y=80)


Label(
    win,
    text=" Click the Below Button to Open the Popup Window",
    font=("Helvetica 14 bold"),
).pack(pady=20)
# Create a button in the main Window to open the popup
ttk.Button(win, text="Open", command=open_popup).pack()
win.mainloop()

@PySimpleGUI is the current work-around to just create a window with alpha = 0.99 instead of a popup?

@PySimpleGUI is the current work-around to just create a window with alpha = 0.99 instead of a popup?

I don't believe we've reached a point where I would consider we have a workaround. We're not there yet. We've found a way to make a window that always appears that's semi-transparent. I wouldn't consider that an acceptable solution. We're getting there, but not there yet.

@ZSamuels28 That's an apples and oranges comparison. If you want to write tkinter code instead of PySimpleGUI code, then I think you're on the right track. The "simple" part of PySimpleGUI is that PySimpleGUI is doing the hard work for you, and leaving you with a simple few lines of code to write. It's going to be a lot more than 10 or 20 lines of tkinter code to duplicate what PySimpleGUI does to create a "simple popup".

My result with @EdwardChamberlain s code.

TOTAL WINDOWS: 200 GOOD WINDOWS: 144 BAD WINDOWS: 56

With alpha workaround: (with hex_color != '#ea3526')
TOTALS:
TOTAL WINDOWS: 200
GOOD WINDOWS: 200
BAD WINDOWS: 0

New version 4.60.0.43 on GitHub

I've uploaded a new version 4.60.0.43 that will print an error message if there is a problem setting the alpha channel when the window is being created. I'm wondering if in the cases that fail if there's an exception happening.

During window creation, the alpha channel is set to 0 so that the drawing can happen hidden and the window can be moved to the final location. Maybe when it's failing to be shown, it's raising an exception that I wasn't displaying (added code to display it in this new version)


Hard coded location test

It may be useful to also run a test where the location of the window is hardcoded to some specific location. I don't recall if someone has already tried this or not. It will change some of the calls that are being made during the window creation if the location is set by the user versus computed.


Delay before trying alpha 1.0

Finally, did anyone try adding a delay after the window is created before trying to set the Alpha all the way to 1? I know we can't do it immediately after the window is created.

The delay could be done using a sleep, or you can do a read with a timeout like this:

window = sg.Window('Window Title', layout, alpha_channel=0.99, finalize=True)

window.read(timeout=1000)           # delay 1 second before trying to set alpha
window.set_alpha(1.0)               # set Alpha all the way to 1.0
commented

@PySimpleGUI I am running:PySimpleGUI==4.60.1. Are you able to advise how I would get 4.60.0.43 please?

commented

Ah - got it.

Running on 4.60.0.43 Unreleased

TOTALS:
TOTAL WINDOWS: 500
 GOOD WINDOWS: 323
  BAD WINDOWS: 177

No exceptions shown in the console.

Hard coded location test

Running

    window = sg.Window('Window Title', layout, location=(100, 100), keep_on_top=True)

Returns:

TOTALS:
TOTAL WINDOWS: 200
 GOOD WINDOWS: 144
  BAD WINDOWS: 56

So no improvement there.

Delay before trying alpha 1.0

Running a window like:

    window = sg.Window('Window Title', layout, alpha_channel=0.99, keep_on_top=True)

    print("Running Window...")
    while True:
        event, values = window.read(timeout=CLOSE_TIME)
        if sg.TIMEOUT_EVENT:
            print("Timeout event...")
            window.set_alpha(1.0)  
            ...  window detection code ....

Gives:

TOTAL WINDOWS: 200
 GOOD WINDOWS: 200
  BAD WINDOWS: 0

So it looks like setting the alpha after the first read will not make it disappear.

Switching to run the set Alpha before the window read however will repeat the issue:

    window = sg.Window('Window Title', layout, alpha_channel=0.99, keep_on_top=True, finalize=True)
    window.set_alpha(1.0)  

    print("Running Window...")
    while True:
        event, values = window.read(timeout=CLOSE_TIME)

        if sg.TIMEOUT_EVENT:
            print("Timeout event...")

gives:

TOTALS:
TOTAL WINDOWS: 50
 GOOD WINDOWS: 39
  BAD WINDOWS: 11

It looks to me like the window needs to be rendered at 0.99 alpha and then switched to 1.0. Attempting to render directly to 1.0 is problematic.

commented

Delving deeper:
Baseline:

TOTALS:
TOTAL WINDOWS: 50
 GOOD WINDOWS: 45
  BAD WINDOWS: 5

Changing line 17166 (that is a lot of lines...) from root.attributes('-alpha', 0) to root.attributes('-alpha', 1)
results in (some horrible jumping around as well as):

TOTALS:
TOTAL WINDOWS: 50
 GOOD WINDOWS: 50
  BAD WINDOWS: 0

Setting line 17166 back to 0 and setting line 17219 from root.attributes('-alpha', alpha_channel) to root.attributes('-alpha', 1) does not resolve the issue:

TOTALS:
TOTAL WINDOWS: 50
 GOOD WINDOWS: 44
  BAD WINDOWS: 6

Looks to me like something in that second conversion back to the set alpha is not working correctly when the alpha is exactly 1 but if it is initially introduced as an alpha 1 window it will render fine. Perhaps macOS doesn't like windows being made invisible.

commented

Next test:
Adding a delay before changing the alpha:

# Line 17226
    try:
        alpha_channel = 1 if window.AlphaChannel is None else window.AlphaChannel
        root.attributes('-alpha', alpha_channel)  # Make window visible again
    except Exception as e:
        print('**** Error setting Alpha Channel to {} after window was created ****'.format(alpha_channel), e)
        # pass

Becomes:

# Line 17226
    try:
        time.sleep(0.2)
        alpha_channel = 1 if window.AlphaChannel is None else window.AlphaChannel
        root.attributes('-alpha', alpha_channel)  # Make window visible again
    except Exception as e:
        print('**** Error setting Alpha Channel to {} after window was created ****'.format(alpha_channel), e)
        # pass

Baseline (where sleep time is commented out / not included as per the current setup):

TOTALS:
TOTAL WINDOWS: 250
 GOOD WINDOWS: 208
  BAD WINDOWS: 42
   PERCENTAGE: 16.80%

with `time.sleep(0.1):

TOTALS:
TOTAL WINDOWS: 250
 GOOD WINDOWS: 247
  BAD WINDOWS: 3
   PERCENTAGE: 1.20%

With `time.sleep(0.2):

TOTALS:
TOTAL WINDOWS: 250
 GOOD WINDOWS: 247
  BAD WINDOWS: 3
   PERCENTAGE: 1.20%

Seems like a delay maybe helps here but its hard to read too much into these numbers as anything else going on could be affecting them without me realising!

commented

Apologies for the absolute spam of posts here!

I was curious if macOS was just permanently dumping any window with 0 alpha randomly (maybe a memory saving thing) so I edited the initial "hide window" code to set the alpha to 0.5 instead of 0.

It didnt help the problem at all, but what was interesting was that the "bad" windows were no longer invisible but now had a 50% opacity. It seems that the first call to set the opacity works fine but the second is occasionally ignored.

I plastered some print statements around the first and second changes to the alpha channel and the program is indeed setting the alpha the second time. The program flow is correct.

I used root.attributes('-alpha') to get the alpha value that TK thinks it has - a good window returned 1.0, a bad window returned 1.0 so no change there.

Ultimately the update in alpha is being called, tk thinks its been done, but it isnt showing on screen.

At this point im a bit lost for an answer. So I try disabling all of the code between the two lines that alter the alpha and enable them one by one. It seems that commenting out _convert_window_to_tk(window) does prevent the alpha problem (while no other lines affect it). this obviously completely destroys the window though.

Chasing it down deeper with the same "what comment disables the problem" approach it seems that within this function the call to PackFormIntoFrame(window, master, window) is causing the issue - removing it removes the problem (again along with a large majority of the window).

This function starts on line 14878 and is massive - almost 2,200 lines and forms the entire backbone of assembling the window. Im also starting to feel more and more like this isnt the right path to finding a solution. Probably enough thinking for today!

Sorry I've been out for a bit. Just coming back long enough to say help is on the way. @Chr0nicT's just M1. We just got off the phone a few minutes ago and he's hot on the issue. He's come through numerous times and I've no doubt something good will come from his help. He's quite familiar with the stretch of the code @EdwardChamberlain has been poking around in.

I've intentionally been keeping us focused on running experiments that don't require getting into that code. That's not where our problems are likely located. Seeing the Alpha being set to 1.0 right after the Window creation failed was a strong indicator that the solution was unlikely in that stretch of code.

Perhaps I should have posted more of the code in the read with a timeout test I was suggesting. Rather than any changes being made to the event loop, my suggestion was to place a read outside the normal event loop. This is how a "patched" program would look.

import PySimpleGUI as sg

layout = [  [sg.Text('My Test Window')],
            [sg.Input(key='-IN-')],
            [sg.Button('Go', bind_return_key=True), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, alpha_channel=0.99, finalize=True)

# The 2-line workaround for the Mac alpha channel bug
window.read(timeout=1000)
window.set_alpha(1.0)

# Your normal, unmodified event loop
while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    if event == 'Go':
        print('exiting')
        break

window.close()

The next question I have is... how low can the quite arbitrary value of 1000 be lowered to and still have a working solution? Dose it have to be 1000? Can it be 500, 50, 10, 1, 0?

Once we get to a workaround, then I'll consider how we go about deploying that... be it inside PySimpleGUI or within the user code. It's highly unlikely to involve a sleep call inside of PySimpleGUI. There are none in the code today.

Let's see how low we can get that timeout.... and see what magic @Chr0nicT can work.

Again sorry about being out of the issues this weekend. I've needed to be heads-down on some other work.

Thanks for working the problem! I've implemented the workaround above, and that seems to do great for the main window. I do make significant use of pop-ups, however, and it seems from reading through the above thread that there's yet no real work-around for them, as you can't set alphas on them?

that there's yet no real work-around for them

This is correct. The issue is quite actively being worked. I get that you use popups. If this is blocking your project to the point you're desperate, then I suggest forking the code and hardcoding the popups you're calling to all use an alpha of .99. I'm working the long-game on this and want a solution that fixed the problem rather than adding a feature that's a hack.

[edit] -- actually, to quickly get the solution you're after, you don't need to "fork" the code. You can simply modify the PySimpleGUI.py file you have installed. Change the popups you're using to each set the alpha channel to .99 and you'll be good to go until I get a better solution together.

Oh, that sounds easy enough, I’ll try! I’m not impatient, however. Totally agree on going for the correct fix versus a quick hack.

I’ve just been developing on my PC instead in the meantime but I’ll give that quick adjustment a try to get the M1 back on its feet for now.

I’ve just been developing on my PC instead in the meantime but I’ll give that quick adjustment a try to get the M1 back on its feet for now.

Oh! That's awesome... and a great idea.

I want to get this solved so you can switch right back from what you're doing now without having to change anything. I do really appreciate your patience. You're not being impatient... you're communicating how you're working and what would help you continue forward the most. There's nothing wrong with that.

Quick update that @Chr0nicT has his new M1 up and running and is able to duplicate the problem. I'll quote his exact words...

I was able to replicate it; I'm trying to find a different approach instead of a timeout, to see what the "root cause" is

That's certainly been his approach on other Mac issues, like the file_types problem. He was able to find a root cause and we got a fix in the code that was far superior to my workaround. So I'm really hoping that he'll work the voodoo magic he seems to know how to do on this one too.

Hello guys, I had the same issue on M1 MBP and is also pleased to tell you that the alpha_channel = 0.99 works very well and I have not seen any invisible windows so far. Instead of adding alpha_channel = 0.99 in your code every time you run, one fix I was able to do was going to the source code of pysimplegui using vs code definition. Then I searched for the keyword "alpha_channel" which was at line 9331 for me. I changed the default value of alpha_channel to 0.99 and saved the file. I know that my solution might be overwritten if I were to update the pysimplegui module. but I hope that my solution helps you to a certain extent, even if temporarily.

How much bleed-through is visible on the M1 when the alpha is 0.99? On windows, I looked through all the themes and there were none that I was able to see any sign of transparency when using an alpha of 0.99.

Are any of you able to perceive transparency when the window renders? How the transparency renders is certainly going to differ between Windows and Mac and may differ between Macs depending on the drivers and hardware. Has anyone noticed their window doesn't look solid?

@Chr0nicT is still working on this one, looking for a root cause and a better workaround. In the meantime, I would like to start to narrow down the workarounds we've been discussing and perhaps get one into the code should we not find the root cause or a better workaround soon.

image

Also... this is important... is anyone seeing this problem on a tkinter release other than 8.6.12? Has anyone tried it on another version of tkinter?

I've got a pretty good eye for graphic artifacts. When I met with @Chr0nicT today, I asked if he's able to visually see a difference on the M1 between an Alpha of 0.99 and 1.0. I'm not able to see a difference that I would consider to be "significant". The area the most impacted was the text rendering. The contrast is slightly lower but not to the point I would consider it to be unacceptable or a complete show-stopper.

I added an alpha_channel parameter to set_options to version 4.60.0.54 . This enables you to globally define the default alpha channel value for all windows PySimpleGUI creates, both user and internally created (i.e. sg.Window and sg.popup).

For the time being, the best workaround I believe is to use add this call to your code:

sg.set_options(alpha_channel=.99)

This is by no means the end of the work...

We are still:

  1. Looking for the root cause
  2. Writing a tkinter sample program that duplicates the problem so the tkinter team can be informed
  3. Trying to find if this happens only on 8.6.12

@PySimpleGUI first, thanks for all the work on this issue! I have the same problem on my M1 MBP. I see that alpha_channel has been removed from set_options in 4.60.1. Does that mean I should stay with 4.60.0.54 until there's a fix per above?

It looks strange, but
4.60.1 - released version, old one
4.60.0.54 - non-released version, new one.

Thank you. Appreciate the quick reply!

I just bumped the GitHub version up to 4.60.1.55 to help with this confusion. Sorry that things got so turned upside down. It's really rare that I do a "dot" release like 4.60.1.

Hopefully even though it's not technically correct that the code strictly evolved following this series of steps,. the actual code in the end looks like it did. I don't see particular harm in going ahead with changing the version on GitHub

I'm meeting with @Chr0nicT on a more frequent basis as we work on this problem.

I added a new option to set_options in version 4.60.1.60 on GitHub. This option turns off the hiding of the Window when the Window is created and moved. I'm interested in knowing if any of you notice a "jumping window" on your M1 with this option set to False.

import PySimpleGUI as sg

sg.set_options(hide_window_when_creating=False)
sg.popup('Test of hide')

I'm adding a new option to the Mac Control Panel that will control the new "Hide Window When Creating" setting.

If version 12.3 or later is found, then the window will not have the alpha channel set to 0 while being created. @Chr0nicT has tested this workaround and in about 1 in 10 windows, you can briefly see the window created elsewhere and then moved. It looks like it is visible for under 100ms to me. It's fast enough that I had to watch specifically for this to happen to notice it.

It'll be the weekend before I can get the code up on GitHub. In the meantime, I urge Mac users to try the set_options call since this is going to be the default setting until the root cause can be found and fixed, likely by Apple.

While not perfect, this solution is superior to the others I think. You'll have the option to choose from several that have been presented so far. It's certainly better than not seeing any window at all.

Can I get some feedback from the Mac users that have commented on this issue?

It would be nice to get a poll of sorts as to what's worked for you out of the menu of numerous workarounds offered?

Also, if you've learned something new about the problem, I certainly want to hear it.

My assumption, and it's always dangerous to assume anything, is that silence is a good sign. May 29 to June 18 was a very action-packed portion of this issue.

Since then, it's been silent for 28 days. The work on this is not done and I'm making some decisions about moving forward and putting this behind us soon. I would like it to be a well-informed decision if possible.

Setting alpha_channel to 0.99 has eliminated the issue on my M1 MBP. There's a version of my app running with the same code base and the production release of PySimpleGui, without the 0.99 fix, and it continues to experience invisible windows.

Can you try the latest fix that uses this bit of code? You do not need to set the alpha channel.

import PySimpleGUI as sg

sg.set_options(hide_window_when_creating=False)

I would like to know if you notice a window moving from some location to the center of the screen or wherever you create your window.

Using "4.60.1.63 Unreleased", with the above set_options, the window draws initially in the upper left of the screen and then redraws in the intended location. It's not subtle - pretty obvious draw-disappear-redraw. (edit) ... possible that window complexity might drive the length of the delay between draw and disappear-redraw. On simple windows it's a "flash". On complex windows with hidden elements the draw-redraw is more obvious.

Thank you for the test. That's what I needed to know. On the Macs we tried, it was barely visible on maybe 1 of 10 times.

Are you using this call to set your alpha?

sg.set_options(alpha_channel=.99)

Of course. Happy to test.

In the first test I removed the alpha_channel setting. Adding it back in a second test doesn't change the behavior. The "flash" is the same when hide_window_when_creating is False.

Sorry I wasn't more clear....You can forget about the attempted fix:

sg.set_options(hide_window_when_creating=False)

My question now is if you have been using this code:

sg.set_options(alpha_channel=.99)

to fix the problem previously or were you setting the Alpha Channel in each Window you created? I'm trying to gauge how much runtime we've got on this set_options fix that was put in 3 weeks ago. I just haven't heard if anyone is successfully using it.

I've been using the global setting with set_options() and it works well

4.60.1.64 just checked in with another option for Mac users.

Back in 4.60.0.4 there was a new feature added that enables users to allow the OS to place the window wherever it chooses.

This new changes enables users to use the set_options call:

sg.set_options(window_location=None)

If the window location is None, then that means the window will never be moved. Since the window is being "created in place" and won't be moved, there's no reason to hide the window... and thus no chance of having an invisible window.

My plan on this is to get a "dot release" out to PyPI.... 4.60.2... ASAP....

We've been investigating if this is homebrew only or if the python from python.org will fix this.

In the meantime, I'm working on a "Fix" that uses the Mac Control Panel to enable / disable the default alpha channel setting. That's the best fix to date and since this needs to happen quickly is what I'll go with.

Please try 4.60.1.65 that was just posted to PyPI.

If you are running Mac OS 12.3+ then the Alpha Channel will automatically be set to 0.99 for you.

You can control this patch in the Mac Feature Control Panel (from sg.main)

image

The patch will only be applied to systems that are Mac OS 12.3 and greater. It is on by default.

If this works out OK for Mac users, then I'll release this patch to PyPI in a dot release of 4.60.2. I've got one ready to go once we've tested this patch out.

You can remove your calls to set_options with this change.

If you're a Mac user that's really into testing and want to help out with this PyPI release, then you'll find the candidate release I've prepared for 4.60.2 here:

https://github.com/PySimpleGUI/PySimpleGUI/tree/4.60.0-dot-releases

4.60.2 was posted to PyPI today. If you upgrade to it, or if you get the latest from GitHub, then you can remove the workaround from your code:

sg.set_options(alpha_channel=.99)

This will be done for you now if PySimpleGUI detects that you are running Mac OS 12.3 or later.

Dang - late to the party again!
I've been having this issue for a while, but only on one of my 2 machines (both Intel):
No problem on:
Python version: 3.10.4 (v3.10.4:9d38120e33, Mar 23 2022, 17:29:05) [Clang 13.0.0 (clang-1300.0.29.30)]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.59.0
MacBookPro - MacOS Big Sur 11.6.7

I do have the issue on:
Python version: 3.10.1 (main, Jan 20 2022, 08:29:54) [Clang 13.0.0 (clang-1300.0.29.30)]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.60.0.3
iMac - MacOS Monterey 12.3.1

I just used pip to get the latest version on my iMac and it took more attempts, but still failed. Also, there appears to be an issue with psgver (maybe the code has not actually updated?):

psgver
/Users/xxxx/.pyenv/versions/3.10.1/lib/python3.10/site-packages/PySimpleGUI/PySimpleGUI.py:22325: UserWarning: _mac_should_seet_alpha_to_99 Exception while trying check mac_ver. Error = could not convert string to float: '12.3.1'
warnings.warn('_mac_should_seet_alpha_to_99 Exception while trying check mac_ver. Error = {}'.format(e), UserWarning)
Python version: 3.10.1 (main, Jan 20 2022, 08:29:54) [Clang 13.0.0 (clang-1300.0.29.30)]
port: tkinter
tkinter version: 8.6.12
PySimpleGUI version: 4.60.2
PySimpleGUI filename: /Users/xxx/.pyenv/versions/3.10.1/lib/python3.10/site-packages/PySimpleGUI/PySimpleGUI.py

Upon further review... my comment about psgver is incorrect.
The problem is in PySimpleGUI @ 22322:
the Mac version string is '12.3.1' - you cannot covert a string with 2 decimal points to a valid float...

Here is my replacement for lines 22326-22333:

    try:
        from packaging import version
        return version.parse(platform.mac_ver()[0]) >= version.parse('12.3')
    except Exception as e:
        warnings.warn('_mac_should_set_alpha_to_99 Exception while trying check mac_ver. Error = {}'.format(e), UserWarning)
        return False

(And I corrected "seet" to "set"...)

Thanks much Bob! That cast to float I had never done with a version number before, and something made me uneasy when I saw it proposed NOW I know why.

image

Not being able to directly and personally test a PyPI release both puts me at a disadvantage and reliant on others to perform the tests. Once I can afford more dedicated Mac help, I'll add it. Until then, it's going to be the fallback position of "the best I can do" and sometimes that's going to come up short. Thank you for countering that weakness, and doing so quicklyu.

I'll get 4.60.3 together today. While I have excuses I can list for my sloppy error, none matter and are not helpful to the situation, so I'll spare everyone my reasons and simply say "I'm sorry". The fact remains that I've got a bad release being actively deployed. I delayed too long before getting this released.

On a personal note, it's fantastic to see your username show up this morning in this issue! Thank you for the help!!

commented

Apologies for the relative radio silence on this issue. Unfortunately, I have been distracted with other work and (fortunately) doing some well needed travel / vacation.

I am still keen to support you with this when I return early next week but I'm glad to see a release with a solution! Does this mean an understanding of the underlying cause has been discovered?

I've just released to GitHub 4.60.3.66 in the main branch and in the dot release branch is the proposed 4.60.3 release.

Does this mean an understanding of the underlying cause has been discovered?

We do not have anything beyond "something changed in Apple's Homebrew release that's with 12.3". That's as "root cause" as we've got. The "Fix" we're testing now is to use the Python.org release as it may, like in the past, not have the problems that homebrew shows. We're in the early stages of testing this. I'm meeting with @Chr0nicT this afternoon to continue working it.

In the meantime, if we can get a little testing done on 4.60.3, that would be great as I want to post it to PyPI ASAP.

Thanks much Bob!!!!!!!

I ended up keeping things a little simpler. I don't want to import another package if possible. Every package adds a little more to EXE files.

The check is split out into an additional variable, platform_mac_ver, so that I could test it on Windows.

        platform_mac_ver = platform.mac_ver()[0]
        mac_ver = platform_mac_ver.split('.')
        if int(mac_ver[0]) >= 12 and int(mac_ver[0]) >= 3:
            print("Mac OS Version is {} and patch enabled so applying the patch".format(platform_mac_ver))
            return True

🕑 - Tick Tock... the PyPI release of 4.60.3 for MAC USERS is paused waiting for verification from a Mac user that it works.

I could use a hand here from someone with this problem. I've got a PyPI release ready to post, but it's not going anywhere until there's confirmation that it works.