Help for screen.reminder

screen ยท reminder

Sample CLI

gway screen reminder

References

Full Code

def reminder(message, *, interval: float = 20.0, daemon=False, lines: int = 2):
    """
    Starts a thread that periodically takes screenshots.
    If the screen hasn't changed between intervals, overlays a reminder
    message and waits for user interaction before resuming.
    """
    import threading
    from PIL import ImageChops
    import pygame
    import ctypes

    def images_equal(img1, img2, threshold=5):
        diff = ImageChops.difference(img1.convert("L"), img2.convert("L"))
        bbox = diff.getbbox()
        if not bbox:
            return True
        stat = diff.crop(bbox).getextrema()
        return stat[1] < threshold

    def bring_to_front():
        if sys.platform == "win32":
            hwnd = pygame.display.get_wm_info()["window"]
            ctypes.windll.user32.SetWindowPos(hwnd, -1, 0, 0, 0, 0, 1 | 2)

    def get_screen_size():
        import tkinter as tk
        root = tk.Tk()
        root.withdraw()
        width = root.winfo_screenwidth()
        height = root.winfo_screenheight()
        root.destroy()
        return (width, height)

    def show_reminder(bg_img: Image.Image):
        import tkinter as tk
        from PIL import ImageTk

        screen_size = get_screen_size()
        reminder_img = render_text(message, size=screen_size, bg=bg_img, lines=lines)

        root = tk.Tk()
        root.title("Reminder")
        root.attributes("-fullscreen", True)
        root.configure(background='black')
        root.focus_force()

        img_tk = ImageTk.PhotoImage(reminder_img)
        label = tk.Label(root, image=img_tk)
        label.pack()

        root.bind("<Key>", lambda e: root.destroy())
        root.bind("<Button>", lambda e: root.destroy())
        root.bind("<Motion>", lambda e: root.destroy())

        root.mainloop()

    def loop():
        reminder_dir = gw.resource("work", "reminder")
        os.makedirs(reminder_dir, exist_ok=True)
        last_img = None

        while True:
            current = ImageGrab.grab()
            current.save(os.path.join(reminder_dir, "next.png"))

            if last_img and images_equal(current, last_img):
                current.save(os.path.join(reminder_dir, "original.png"))
                show_reminder(current)

            last_img = current
            time.sleep(float(interval))

    thread = threading.Thread(target=loop, daemon=daemon)
    thread.start()

    if not daemon:
        try:
            while thread.is_alive():
                thread.join(timeout=1)
        except (KeyboardInterrupt, EOFError):
            print("Exiting reminder.")
            return

    return thread