From 5f9dc9b5b2498287dbf75e5442fef6e6040d47a0 Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Tue, 4 Nov 2025 16:32:49 -0500 Subject: [PATCH 01/12] indent to fix linting error --- src/core/gui_root.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/gui_root.py b/src/core/gui_root.py index 4e88d24..da23dc3 100644 --- a/src/core/gui_root.py +++ b/src/core/gui_root.py @@ -232,7 +232,7 @@ def show_logs(self, _=None): f"Platform: {platform.system()} ({platform.machine()})\n" f"{'=' * 21}\n" f"NOTE: logs window only refreshes when reopened.\n\n" - ) + ) # Read logs from the log file if available log_contents = "" From f5889d7a362265f3b0cf2dfc69b97484da710536 Mon Sep 17 00:00:00 2001 From: Adam Blair-Smith Date: Tue, 4 Nov 2025 16:43:13 -0500 Subject: [PATCH 02/12] Update README with building instructions Added building instructions and requirements for the project. --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 6ecad9d..5575b59 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,20 @@ To install, follow the instructions for your platform found here: NOTE: GIL is detached for the macOS build; use Python 3.13.7t +## Building + +For building, it is recommended to use Python 3.13.7 for Windows/Linux, and 3.13.7t for macOS in a virtual enviroment. + +Install requirents: +`pip install -r requirements.txt` + +Run build script: +`python build.py` + +The resulting AppUsageGUI folder will be created in dist/ + +Scripts to create macOS/Windows installers are located in dev/ + ## How It Works AppUsageGUI is a cross-platform desktop application built with Python and Tkinter that monitors application usage time with project-based organization. The application works by: From 4750593c5e1ea44e84da16aa255f1d255f5200b3 Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sat, 8 Nov 2025 18:32:29 -0500 Subject: [PATCH 03/12] Fixed "Copy Logs" button not working #31 --- src/core/gui_root.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/gui_root.py b/src/core/gui_root.py index 4e88d24..a789879 100644 --- a/src/core/gui_root.py +++ b/src/core/gui_root.py @@ -261,7 +261,7 @@ def show_logs(self, _=None): btn_frame.columnconfigure(0, weight=1) btn_frame.columnconfigure(1, weight=1) - def copy_logs(): + def logs(): """Read the log file and return its contents.""" try: if os.path.exists(self.log_file_path): @@ -271,6 +271,16 @@ def copy_logs(): return "(Log file not found)" except Exception as e: return f"(Failed to read log file: {e})" + + def copy_logs(): + """Copy the current logs to the clipboard.""" + import pyperclip + try: + log_text = header + logs() + pyperclip.copy(log_text) + messagebox.showinfo("Copy Logs", "Logs copied to clipboard.") + except Exception as e: + messagebox.showerror("Copy Logs", f"Failed to copy logs: {e}") ttk.Button(btn_frame, text="Copy Logs", command=copy_logs).grid(row=0, column=0, sticky="w", padx=(8, 0)) ttk.Button(btn_frame, text="Close", command=win.destroy).grid(row=0, column=1, sticky="e", padx=(0, 8)) @@ -279,7 +289,7 @@ def copy_logs(): def refresh_logs(): """Refresh the logs displayed in the logs window.""" try: - new_text = header + copy_logs() # Use copy_logs() to get log content + new_text = header + logs() # Use logs() to get log content text_box.config(state="normal") text_box.delete(1.0, "end") # Clear existing content text_box.insert("end", new_text) # Insert new content From 2ef3e7b9d3d738640b3f8de2d880f4c732f41372 Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sat, 8 Nov 2025 18:36:05 -0500 Subject: [PATCH 04/12] bump pyperclip to 1.11.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 71cbc94..6e67274 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ PyMsgBox==1.0.9 pyobjc-core==11.0; sys_platform == "darwin" pyobjc-framework-Cocoa==11.0; sys_platform == "darwin" pyobjc-framework-Quartz==11.0; sys_platform == "darwin" -pyperclip==1.9.0 +pyperclip==1.11.0 PyRect==0.2.0 PyScreeze==1.0.1 pytweening==1.2.0 From 3df202aec9d2923b287694771ccfee6832d95ebf Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sat, 8 Nov 2025 18:38:42 -0500 Subject: [PATCH 05/12] removed unused requirement MouseInfo --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6e67274..2a7eabf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -MouseInfo==0.1.3 psutil==7.1.0 pynput==1.8.1 PyGetWindow==0.0.9 From cae475786d147fcbf1c25c31bbed8fc80e925d9f Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sat, 8 Nov 2025 18:40:13 -0500 Subject: [PATCH 06/12] removed requirement pygetwindow --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2a7eabf..a32c449 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ psutil==7.1.0 pynput==1.8.1 -PyGetWindow==0.0.9 PyMsgBox==1.0.9 pyobjc-core==11.0; sys_platform == "darwin" pyobjc-framework-Cocoa==11.0; sys_platform == "darwin" From 1ce68cd50e19ec06ecd71c91a50ee812b6dd5604 Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sat, 8 Nov 2025 18:42:59 -0500 Subject: [PATCH 07/12] removed requirement PyRect --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a32c449..e595931 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,6 @@ pyobjc-core==11.0; sys_platform == "darwin" pyobjc-framework-Cocoa==11.0; sys_platform == "darwin" pyobjc-framework-Quartz==11.0; sys_platform == "darwin" pyperclip==1.11.0 -PyRect==0.2.0 PyScreeze==1.0.1 pytweening==1.2.0 rubicon-objc==0.5.0 From ec219088b5bf315c0707f0032a0cc6cc553d84d8 Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sat, 8 Nov 2025 23:50:14 -0500 Subject: [PATCH 08/12] improved logging --- src/core/gui_root.py | 2 +- src/core/logic/app_tracker.py | 5 +++-- src/core/logic/user_trackers.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/gui_root.py b/src/core/gui_root.py index faadd5f..af6a28a 100644 --- a/src/core/gui_root.py +++ b/src/core/gui_root.py @@ -274,7 +274,7 @@ def logs(): def copy_logs(): """Copy the current logs to the clipboard.""" - import pyperclip + import pyperclip # type: ignore try: log_text = header + logs() pyperclip.copy(log_text) diff --git a/src/core/logic/app_tracker.py b/src/core/logic/app_tracker.py index a48a132..990811d 100644 --- a/src/core/logic/app_tracker.py +++ b/src/core/logic/app_tracker.py @@ -1,6 +1,6 @@ import threading import os -import psutil +import psutil # type: ignore import sys if os.name == 'nt': @@ -8,7 +8,7 @@ from pywinauto.findwindows import ElementNotFoundError windows = Desktop(backend="uia").windows() elif sys.platform == 'darwin': - from AppKit import NSWorkspace + from AppKit import NSWorkspace # type: ignore from core.utils.file_utils import read_file, write_file, apps_file, user_dir_exists, config_file @@ -98,6 +98,7 @@ def stop(self): if self.update_thread is not None: try: self.update_thread.join() + logging.info("App tracker stopped.") except RuntimeError: pass diff --git a/src/core/logic/user_trackers.py b/src/core/logic/user_trackers.py index c9b6ef7..0e5e770 100644 --- a/src/core/logic/user_trackers.py +++ b/src/core/logic/user_trackers.py @@ -4,7 +4,7 @@ """ import threading -import pynput +import pynput # type: ignore from core.utils.file_utils import read_file, config_file @@ -68,9 +68,9 @@ def stop(self): if self.update_thread is not None: try: self.update_thread.join() + logging.info("Mouse tracker stopped.") except RuntimeError: pass - logging.info("Mouse tracker stopped.") def set_enabled(self, enabled=bool): self.enabled = enabled From b07bf846c19cb3d21d478a68cc84d20c7dc3cfaa Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sat, 8 Nov 2025 23:52:06 -0500 Subject: [PATCH 09/12] versioning for 1.8.2 --- README.md | 2 +- dev/macos_installer.sh | 2 +- dev/windows_installer.iss | 4 ++-- src/_version.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5575b59..be1a92a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![version](https://img.shields.io/badge/Version-1.8.1-white.svg) +![version](https://img.shields.io/badge/Version-1.8.2-white.svg) ![license](https://img.shields.io/badge/License-GPL%20v3-blue.svg) ![python](https://img.shields.io/badge/Python-3.13-green.svg) diff --git a/dev/macos_installer.sh b/dev/macos_installer.sh index af22758..887caa9 100644 --- a/dev/macos_installer.sh +++ b/dev/macos_installer.sh @@ -1,6 +1,6 @@ #!/bin/bash # This script is used to create the installer for the macOS version of the application -app_version='1.8.1' +app_version='1.8.2' mv dist/AppUsageGUI.app dist/AppUsageGUI/ diff --git a/dev/windows_installer.iss b/dev/windows_installer.iss index 047df9d..e9b62b8 100644 --- a/dev/windows_installer.iss +++ b/dev/windows_installer.iss @@ -2,11 +2,11 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "AppUsageGUI" -#define MyAppVersion "1.8.1" +#define MyAppVersion "1.8.2" #define MyAppPublisher "Adam Blair-Smith" #define MyAppURL "https://github.com/Adam-Color/AppUsageGUI" #define MyAppExeName "AppUsageGUI.exe" -#define MyInstallerName "AppUsageGUI_v1.8.1_WINDOWS_setup" +#define MyInstallerName "AppUsageGUI_v1.8.2_WINDOWS_setup" [Setup] ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. diff --git a/src/_version.py b/src/_version.py index 2d986fc..320141d 100644 --- a/src/_version.py +++ b/src/_version.py @@ -1 +1 @@ -__version__ = "1.8.1" +__version__ = "1.8.2" From 6addefd376124c03127cb0e929328979e1d381fa Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sun, 9 Nov 2025 00:01:47 -0500 Subject: [PATCH 10/12] Logging now keeps last 20 logs --- src/_logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_logging.py b/src/_logging.py index 3df47c6..1b4bf15 100644 --- a/src/_logging.py +++ b/src/_logging.py @@ -18,7 +18,7 @@ def setup_logging(): rotating_handler = RotatingFileHandler( log_file, maxBytes=2_000_000, # 2 MB before rotating - backupCount=5, # keep 5 old log files + backupCount=20, # keep 20 old log files encoding='utf-8' ) From e087183dfee214e8d59cbb9a33403be7276bc4ef Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Sun, 9 Nov 2025 00:10:38 -0500 Subject: [PATCH 11/12] update release template --- docs/release_template.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/release_template.md b/docs/release_template.md index a4cf16c..233a2dd 100644 --- a/docs/release_template.md +++ b/docs/release_template.md @@ -1,5 +1,8 @@ # AppUsageGUI v0.0.0 +>[!warning] +>Due to Apple's restrictions when it comes to open source applications such as ours, workarounds are needed to get AppUsageGUI to run on macOS. Please read the installation instructions below. + To install, follow the instructions for your platform found here: [Windows](https://github.com/Adam-Color/AppUsageGUI/blob/Develop/docs/install_windows.md) | [macOS](https://github.com/Adam-Color/AppUsageGUI/blob/Develop/docs/install_macos.md) From 6fd2f6277004976e9c1dcd63afeefad28fbffe17 Mon Sep 17 00:00:00 2001 From: Techi-Joe Date: Mon, 10 Nov 2025 00:39:47 -0500 Subject: [PATCH 12/12] added pyperclip to build.py --- build.py | 1 + 1 file changed, 1 insertion(+) diff --git a/build.py b/build.py index bdb9684..19f0ee6 100644 --- a/build.py +++ b/build.py @@ -45,6 +45,7 @@ def build_executable(): f'--collect-submodules pynput ' f'--collect-submodules requests ' f'--collect-submodules PIL ' + f'--collect-submodules pyperclip ' f'--exclude-module PIL.tests ' f'--exclude-module tkinter.test ' f'--icon={icon_file} '