Skip to content

Commit dd8a7f1

Browse files
committed
fixed the new features on windows
1 parent 344f9e8 commit dd8a7f1

4 files changed

Lines changed: 51 additions & 33 deletions

File tree

src/core/gui_root.py

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __init__(self, parent):
5252

5353
# Options list
5454
self.options = [
55-
{"label": "Update", "callback": self.update_and_check},
55+
{"label": "Update Check", "callback": self.update_and_check},
5656
{"label": "Logs", "callback": self.show_logs},
5757
{"label": "License", "callback": self.show_license},
5858
{"label": "About", "callback": self.show_about},
@@ -130,12 +130,18 @@ def show_about(self, _=None):
130130
)
131131

132132
def show_license(self, _=None):
133-
"""Open license file in a scrollable popup window (reusable)."""
133+
"""Open license file in a scrollable popup window (resizable, with fixed footer)."""
134+
# --- Prevent duplicate windows ---
135+
if hasattr(self, "license_window") and self.license_window and self.license_window.winfo_exists():
136+
self.license_window.lift()
137+
self.license_window.focus_force()
138+
return
139+
134140
license_paths_to_try = [
135141
"_internal/LICENSE.txt",
136142
"LICENSE.txt",
137143
os.path.join(os.path.dirname(__file__), "_internal", "LICENSE.txt"),
138-
resource_path("LICENSE.txt")
144+
resource_path("LICENSE.txt"),
139145
]
140146

141147
text = None
@@ -146,7 +152,6 @@ def show_license(self, _=None):
146152
text = f.read()
147153
break
148154
except Exception:
149-
# ignore and try next
150155
pass
151156

152157
if text is None:
@@ -155,85 +160,96 @@ def show_license(self, _=None):
155160
messagebox.showerror("License", error_txt)
156161
return
157162

158-
# Reusable Toplevel license window
159163
win = tk.Toplevel(self.parent)
164+
self.license_window = win # keep reference
160165
win.title("License")
161166
win.geometry("600x600")
162167
win.transient(self.parent)
163168
win.resizable(True, True)
164169
center_relative_to_parent(win, self.parent)
170+
win.protocol("WM_DELETE_WINDOW", lambda: (win.destroy(), setattr(self, "license_window", None)))
171+
172+
win.rowconfigure(0, weight=1)
173+
win.columnconfigure(0, weight=1)
165174

166-
# Use a frame for padding and layout
167175
frame = ttk.Frame(win, padding=(8, 8, 8, 8))
168-
frame.pack(fill="both", expand=True)
176+
frame.grid(row=0, column=0, sticky="nsew")
177+
frame.rowconfigure(0, weight=1)
178+
frame.columnconfigure(0, weight=1)
169179

170-
# Text widget + scrollbar
171180
text_box = tk.Text(frame, wrap="word", borderwidth=0)
172181
text_box.insert("1.0", text)
173-
text_box.config(state="disabled") # read-only
174-
text_box.pack(side="left", fill="both", expand=True)
182+
text_box.config(state="disabled")
183+
text_box.grid(row=0, column=0, sticky="nsew")
175184

176185
scrollbar = ttk.Scrollbar(frame, orient="vertical", command=text_box.yview)
177-
scrollbar.pack(side="right", fill="y")
186+
scrollbar.grid(row=0, column=1, sticky="ns")
178187
text_box.config(yscrollcommand=scrollbar.set)
179188

180-
# Close button
181189
btn_frame = ttk.Frame(win)
182-
btn_frame.pack(fill="x", pady=(6, 8))
183-
close_btn = ttk.Button(btn_frame, text="Close", command=win.destroy)
184-
close_btn.pack(side="right", padx=(0, 8))
190+
btn_frame.grid(row=1, column=0, sticky="ew", pady=(6, 8))
191+
btn_frame.columnconfigure(0, weight=1)
192+
ttk.Button(btn_frame, text="Close", command=win.destroy).grid(row=0, column=0, sticky="e", padx=(0, 8))
193+
185194

186195
def update_and_check(self, _=None):
187-
if new_updates():
196+
if new_updates(manual_check=True):
188197
update()
189198
else:
190199
messagebox.showinfo("Update", "No new updates available.")
191200

192201
def show_logs(self, _=None):
193-
"""Display live-updating logs in a scrollable window with timestamped header and copy button."""
202+
"""Display live-updating logs in a scrollable window with fixed footer buttons."""
194203
win = tk.Toplevel(self.parent)
195204
win.title("Application Logs")
196-
win.geometry("400x500")
205+
win.geometry("600x600")
197206
win.transient(self.parent)
198207
center_relative_to_parent(win, self.parent)
199208

209+
# Use grid instead of pack for better control
210+
win.rowconfigure(0, weight=1)
211+
win.columnconfigure(0, weight=1)
212+
200213
frame = ttk.Frame(win, padding=(8, 8, 8, 8))
201-
frame.pack(fill="both", expand=True)
214+
frame.grid(row=0, column=0, sticky="nsew")
215+
frame.rowconfigure(0, weight=1)
216+
frame.columnconfigure(0, weight=1)
202217

203-
# Prepare header (once)
218+
# --- Header and text setup ---
204219
header = (
205220
f"=== {self.parent.title()} ===\n"
206-
f"Session started: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
207-
f"Python: {sys.version.split("(")[0]}\n"
221+
f"Logging Started: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
222+
f"Python: {sys.version.split()[0]}\n"
208223
f"Platform: {platform.system()} ({platform.machine()})\n"
209224
f"Config: {read_file(config_file())}\n"
210225
f"{'=' * 30}\n\n"
211226
)
212227

213-
# Combine header and current log contents
214228
initial_text = header + (self.log_stream.getvalue() or "(No logs yet)\n")
215229

216230
text_box = tk.Text(frame, wrap="word")
217231
text_box.insert("1.0", initial_text)
218232
text_box.config(state="disabled")
219-
text_box.pack(side="left", fill="both", expand=True)
233+
text_box.grid(row=0, column=0, sticky="nsew")
220234

221235
scrollbar = ttk.Scrollbar(frame, orient="vertical", command=text_box.yview)
222-
scrollbar.pack(side="right", fill="y")
236+
scrollbar.grid(row=0, column=1, sticky="ns")
223237
text_box.config(yscrollcommand=scrollbar.set)
224238

239+
# --- Buttons at bottom (separate frame) ---
225240
btn_frame = ttk.Frame(win)
226-
btn_frame.pack(fill="x", pady=(6, 8))
241+
btn_frame.grid(row=1, column=0, sticky="ew", pady=(6, 8))
242+
btn_frame.columnconfigure(0, weight=1)
243+
btn_frame.columnconfigure(1, weight=1)
227244

228245
def copy_logs():
229-
"""Copy full logs (with header) to clipboard."""
230246
full_text = header + self.log_stream.getvalue()
231247
win.clipboard_clear()
232248
win.clipboard_append(full_text)
233249
messagebox.showinfo("Logs", "Logs copied to clipboard.")
234250

235-
ttk.Button(btn_frame, text="Copy Logs", command=copy_logs).pack(side="left", padx=(8, 0))
236-
ttk.Button(btn_frame, text="Close", command=win.destroy).pack(side="right", padx=(0, 8))
251+
ttk.Button(btn_frame, text="Copy Logs", command=copy_logs).grid(row=0, column=0, sticky="w", padx=(8, 0))
252+
ttk.Button(btn_frame, text="Close", command=win.destroy).grid(row=0, column=1, sticky="e", padx=(0, 8))
237253

238254
# --- Live Updating ---
239255
def refresh_logs():

src/core/screens/splash_screen.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def load_app():
100100
from core.utils.app_utils import new_updates
101101
if new_updates():
102102
from core.utils.app_utils import update
103+
update()
103104
update_progress(70)
104105
from core.gui_root import GUIRoot
105106
update_progress(80)

src/core/screens/tracker_window.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,11 @@ def _update_time_label(self):
141141
if round(self.logic.time_tracker.get_elapsed_time()) > 0:
142142
self.controller.show_frame("SaveWindow")
143143
else:
144+
error_msg = "The tracked application is not running and cannot be found.\nThis session cannot be continued because the target application is not available."
145+
print(error_msg)
144146
messagebox.showerror(
145147
"App Not Found",
146-
"The tracked application is not running and cannot be found.\n"
147-
"This session cannot be continued because the target application is not available."
148+
error_msg
148149
)
149150
self.controller.reset_frames()
150151
self.controller.show_frame("MainWindow")

src/core/utils/app_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from core.utils.tk_utils import messagebox
22

3-
def new_updates():
3+
def new_updates(manual_check=False):
44
"""Check for new updates on GitHub. Returns a boolean"""
55
import os
66
from core.utils.file_utils import read_file, write_file, config_file
@@ -24,7 +24,7 @@ def new_updates():
2424
settings.update({"last_update_check": last_update_check})
2525
write_file(config_file(), settings)
2626

27-
if time.time() - last_update_check < 43200:
27+
if time.time() - last_update_check < 43200 and not manual_check:
2828
return False # Check for updates only once every 12 hours
2929

3030
settings.update({"last_update_check": time.time()})

0 commit comments

Comments
 (0)