#==================================================================================== # 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()