File: frigcal-products/unzipped/frigcal-main.py

#====================================================================================
# Main Frigcal run logic (run alone or from GUI frigcal-launcher.pyw)
#====================================================================================

# [3.0] split off from frigcal.py to here and add imports to to fix circular import 
# if code in frigcal.py, program worked, but frigcal.py code was imported/run twice

import searchcals_dialog    # import first, to trigger a _nested_ frigcal.py import 
from frigcal import *       # use now-complete figcal.py, (imports searchcals_dialog)
from tkinter.messagebox import showinfo


def main(prototype=PROTO):                         # prototype now fully deprecated

    if RunningOnWindows:
        """
        ---------------------------------------------------------------------------
        [3.0] auto deblur tkinter GUIs, wheter run by python.exe or standalone exe;
        this must be run before creating any UI components in the calling process;
        also done in tools scripts that are built as standalone executables;

        an older and limited alternative to the Kivy PPUS app code adopted ahead:
        from ctypes import windll
        windll.shcore.SetProcessDpiAwareness(2)    # 2=per monitor, 1=main monitor

        https://github.com/kivy/kivy/pull/7299
        https://learning-python.com/post-release-updates.html#win10blurryguis
        https://learn.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context
        ---------------------------------------------------------------------------
        """
        from ctypes import windll, c_int64
        windll.user32.SetProcessDpiAwarenessContext(c_int64(-4))   # per monitor aware v2

    try:
        icsfiletools.init_default_ics_file()       # if none on first run (or bad path)
        icsfiletools.parse_ics_files()             # makes CalendarsTable, EventsTable
    except:
        startuperror(                              # [1.5] GUI popup, not console only
            'Error while loading calendar.\n\n'
            'Check your "icspath" setting in frigcal_configs.py first.  '
            "Then check your calendar folder's permissions, and your "
            "calendar data's validity.\n\n"
            'Python exception text follows:\n\n%s\n%s'
            % (sys.exc_info()[0], sys.exc_info()[1]))
    else:
        # [2.0] make sentinel file in cwd to signal
        # launcher to close (if run), ignore errors
        try:
            open('.frigcal-is-active', 'w').close()
        except:
            pass
        
        # the normal bit
        root = Tk()
        main = MonthWindow(root)

        if hasattr(sys, 'frozen') and RunningOnWindows: 
            #--------------------------------------------------------------------
            # [3.0] yes, must tell PyInstaller splash screen to close, atfer
            # the main window is built.  The ss might be a custom thing here.
            #--------------------------------------------------------------------
            import pyi_splash
            pyi_splash.close()

        # [2.0] on Mac, customize app-wide automatic top-of-display menu
        fixAppleMenuBar(window=root,
                        appname=PROGRAM,
                        helpaction=lambda: webbrowser.open(HELPFILE),
                        # [3.0] About != Help
                        aboutaction=lambda:
                            showinfo(f'About {PROGRAM}',
                                     f'{PROGRAM} version {VERSION}\n'
                                      'See Help for more info'),
                        quitaction=main.onQuit)    # app-wide quit: save/ask

        if RunningOnMacOS:
            #--------------------------------------------------------------------
            # [2.0] required on Mac OS X (only), else the checkbuttons in the
            # main window are not displayed in Aqua (blue) active-window style
            # until users click another window and click this program's window;
            #
            # this is a bug in AS's Mac Tk 8.5 -- it's not present in other Tk 
            # ports, and IDLE search dialogs have the same issue;  for reasons 
            # TBD, it's enough to use just the lift() below for frigcal when 
            # it is run from a command line, but the full bit here is required 
            # when run by mac pylaucher on a click;  ditto for pymailgui, but 
            # mergeall requires all 3 steps in both contexts (it's special?...);
            # caveat: can still lose active style on iconify and common dialogs;
            #
            # UPDATE: focus is now restored after common dialog closes by a 
            # focus_force(), and on deiconifies (unhides) by catching Dock 
            # clicks and running the heinous hack copied from mergeall below;
            #--------------------------------------------------------------------
  
            # fix tk focus loss on startup
            root.withdraw()
            root.lift()
            root.after_idle(root.deiconify)

            # fix tk focus loss on deiconify
            def onReopen():
                #print(root.state())    # always normal
                root.lift()
                root.update()
                temp = Toplevel()
                temp.lower()
                temp.destroy()
            root.createcommand('::tk::mac::ReopenApplication', onReopen)

        root.mainloop()

        # [2.0] clean up sentinel file on exit,
        # else it's deleted on next launcher run
        try:
            os.remove('.frigcal-is-active')
        except:
            pass


if __name__ == '__main__':
    main()



[Home page] Books Code Blog Python Author Train Find ©M.Lutz