screenoverlay 0.5.0__tar.gz → 0.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/PKG-INFO +1 -1
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/screenoverlay/__init__.py +1 -1
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/screenoverlay/overlay.py +175 -205
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/screenoverlay.egg-info/PKG-INFO +1 -1
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/setup.py +1 -1
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/LICENSE +0 -0
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/README.md +0 -0
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/screenoverlay.egg-info/SOURCES.txt +0 -0
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/screenoverlay.egg-info/dependency_links.txt +0 -0
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/screenoverlay.egg-info/requires.txt +0 -0
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/screenoverlay.egg-info/top_level.txt +0 -0
- {screenoverlay-0.5.0 → screenoverlay-0.6.1}/setup.cfg +0 -0
|
@@ -2,17 +2,14 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Native Blur Overlay - Uses OS-native blur effects
|
|
4
4
|
No screen capture, no permissions needed, instant appearance
|
|
5
|
+
|
|
6
|
+
Single-process architecture using Tkinter's update() for non-blocking operation.
|
|
5
7
|
"""
|
|
6
8
|
|
|
7
9
|
import tkinter as tk
|
|
8
10
|
import platform
|
|
9
11
|
import sys
|
|
10
12
|
import os
|
|
11
|
-
import threading
|
|
12
|
-
from multiprocessing import Process, Queue
|
|
13
|
-
import time
|
|
14
|
-
import atexit
|
|
15
|
-
import signal
|
|
16
13
|
|
|
17
14
|
# Try to import screeninfo for multi-monitor support
|
|
18
15
|
try:
|
|
@@ -65,154 +62,170 @@ class NativeBlurOverlay:
|
|
|
65
62
|
|
|
66
63
|
self.root = None
|
|
67
64
|
self.windows = [] # List to hold multiple windows for multi-monitor
|
|
68
|
-
self.
|
|
69
|
-
self.
|
|
70
|
-
self._command_queue = None
|
|
71
|
-
|
|
72
|
-
# Register cleanup on exit to prevent orphaned processes
|
|
73
|
-
atexit.register(self._cleanup_on_exit)
|
|
74
|
-
|
|
75
|
-
def _cleanup_on_exit(self):
|
|
76
|
-
"""Cleanup overlay process on program exit"""
|
|
77
|
-
if self._process is not None and self._process.is_alive():
|
|
78
|
-
try:
|
|
79
|
-
# Try graceful stop first
|
|
80
|
-
if self._command_queue is not None:
|
|
81
|
-
try:
|
|
82
|
-
self._command_queue.put('stop')
|
|
83
|
-
except:
|
|
84
|
-
pass
|
|
85
|
-
|
|
86
|
-
# Wait briefly
|
|
87
|
-
self._process.join(timeout=0.5)
|
|
88
|
-
|
|
89
|
-
# Force kill if still alive
|
|
90
|
-
if self._process.is_alive():
|
|
91
|
-
self._process.terminate()
|
|
92
|
-
self._process.join(timeout=0.5)
|
|
93
|
-
|
|
94
|
-
# Last resort - force kill
|
|
95
|
-
if self._process.is_alive():
|
|
96
|
-
self._process.kill()
|
|
97
|
-
except:
|
|
98
|
-
pass
|
|
65
|
+
self._is_visible = False
|
|
66
|
+
self._last_update_time = 0 # Throttle update() calls
|
|
99
67
|
|
|
100
68
|
def start(self):
|
|
101
69
|
"""
|
|
102
|
-
|
|
70
|
+
Initialize the overlay windows.
|
|
103
71
|
Call this once at app startup.
|
|
104
72
|
|
|
105
|
-
After calling start(), use show() and hide() to control visibility instantly
|
|
73
|
+
After calling start(), use show() and hide() to control visibility instantly,
|
|
74
|
+
and call update() regularly in your main loop to keep the overlay responsive.
|
|
106
75
|
|
|
107
|
-
Example
|
|
76
|
+
Example:
|
|
108
77
|
overlay = Overlay(mode='blur', blur_strength=4)
|
|
109
78
|
overlay.start() # Initialize (call once)
|
|
110
79
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
80
|
+
while True:
|
|
81
|
+
overlay.show() # Show overlay (instant)
|
|
82
|
+
time.sleep(2)
|
|
83
|
+
overlay.hide() # Hide overlay (instant)
|
|
84
|
+
overlay.update() # Keep overlay responsive (call regularly!)
|
|
115
85
|
|
|
116
86
|
overlay.stop() # Cleanup when done
|
|
117
87
|
"""
|
|
118
|
-
if self.
|
|
119
|
-
return
|
|
88
|
+
if self.root is not None:
|
|
89
|
+
return # Already started
|
|
120
90
|
|
|
121
|
-
|
|
122
|
-
self.
|
|
123
|
-
self._process.start()
|
|
91
|
+
# Create windows for all monitors
|
|
92
|
+
self._create_windows()
|
|
124
93
|
|
|
125
|
-
#
|
|
126
|
-
|
|
94
|
+
# Hide all windows initially
|
|
95
|
+
for win in self.windows:
|
|
96
|
+
win.withdraw()
|
|
97
|
+
|
|
98
|
+
self._is_visible = False
|
|
127
99
|
|
|
128
100
|
def show(self):
|
|
129
|
-
"""Show the overlay (instant,
|
|
130
|
-
|
|
131
|
-
|
|
101
|
+
"""Show the overlay (instant, <1ms)"""
|
|
102
|
+
import traceback
|
|
103
|
+
print(f"\n🔴 OVERLAY.SHOW() CALLED! Stack trace:")
|
|
104
|
+
traceback.print_stack()
|
|
105
|
+
|
|
106
|
+
if self.root is None:
|
|
107
|
+
# Auto-start if not started yet
|
|
108
|
+
self.start()
|
|
109
|
+
|
|
110
|
+
if not self._is_visible:
|
|
111
|
+
for win in self.windows:
|
|
112
|
+
try:
|
|
113
|
+
win.deiconify()
|
|
114
|
+
win.attributes('-topmost', True) # Re-enable topmost when showing
|
|
115
|
+
win.lift()
|
|
116
|
+
except Exception as e:
|
|
117
|
+
print(f"Warning: Failed to show window: {e}")
|
|
118
|
+
self._is_visible = True
|
|
119
|
+
print(f"✅ OVERLAY IS NOW VISIBLE\n")
|
|
132
120
|
|
|
133
121
|
def hide(self):
|
|
134
|
-
"""
|
|
135
|
-
|
|
122
|
+
"""Hide the overlay by DESTROYING and RECREATING it (prevents ghost windows/CPU leaks)"""
|
|
123
|
+
import traceback
|
|
124
|
+
print(f"\n⚪ OVERLAY.HIDE() CALLED! Stack trace:")
|
|
125
|
+
traceback.print_stack()
|
|
136
126
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
2. Stops the overlay process completely (kills any ghost windows)
|
|
140
|
-
3. Starts a fresh overlay ready for next show() (happens in background ~300ms)
|
|
127
|
+
if self.root is None:
|
|
128
|
+
return # Not started yet
|
|
141
129
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
130
|
+
if self._is_visible:
|
|
131
|
+
# COMPLETE DESTRUCTION - no lingering windows or events!
|
|
132
|
+
print(f"🗑️ DESTROYING overlay completely...")
|
|
133
|
+
try:
|
|
134
|
+
# Just destroy root - it will destroy all child windows automatically
|
|
135
|
+
if self.root:
|
|
136
|
+
try:
|
|
137
|
+
self.root.destroy()
|
|
138
|
+
except Exception as e:
|
|
139
|
+
print(f"Warning: destroy() failed: {e} (might already be destroyed)")
|
|
140
|
+
except Exception as e:
|
|
141
|
+
print(f"Warning: Failed to destroy overlay: {e}")
|
|
142
|
+
|
|
143
|
+
self.root = None
|
|
144
|
+
self.windows = []
|
|
145
|
+
self._is_visible = False
|
|
146
|
+
print(f"✅ OVERLAY DESTROYED\n")
|
|
147
|
+
|
|
148
|
+
# SAFETY CHECK: Verify system is clean before recreating
|
|
149
|
+
print(f"🔍 SAFETY CHECK: Verifying clean state...")
|
|
150
|
+
if self.root is not None:
|
|
151
|
+
print(f"⚠️ WARNING: self.root is not None after destroy! Force clearing...")
|
|
152
|
+
self.root = None
|
|
153
|
+
if len(self.windows) > 0:
|
|
154
|
+
print(f"⚠️ WARNING: self.windows has {len(self.windows)} entries after destroy! Force clearing...")
|
|
155
|
+
self.windows = []
|
|
156
|
+
if self._is_visible:
|
|
157
|
+
print(f"⚠️ WARNING: _is_visible is True after destroy! Force clearing...")
|
|
158
|
+
self._is_visible = False
|
|
149
159
|
|
|
150
|
-
#
|
|
151
|
-
|
|
160
|
+
# Small delay to let Tkinter/macOS fully cleanup
|
|
161
|
+
import time
|
|
162
|
+
time.sleep(0.01) # 10ms delay for cleanup
|
|
163
|
+
print(f"✅ SYSTEM CLEAN\n")
|
|
152
164
|
|
|
153
|
-
#
|
|
165
|
+
# RECREATE FRESH for next show()
|
|
166
|
+
print(f"♻️ RECREATING fresh overlay...")
|
|
154
167
|
self.start()
|
|
168
|
+
print(f"✅ FRESH OVERLAY READY (hidden)\n")
|
|
169
|
+
|
|
170
|
+
def update(self):
|
|
171
|
+
"""
|
|
172
|
+
Keep overlay responsive - call this regularly in your main loop!
|
|
173
|
+
|
|
174
|
+
This processes Tkinter events and keeps the windows responsive.
|
|
175
|
+
Without calling this, the overlay will freeze.
|
|
176
|
+
|
|
177
|
+
Example:
|
|
178
|
+
while True:
|
|
179
|
+
detect_something()
|
|
180
|
+
if detected:
|
|
181
|
+
overlay.show()
|
|
182
|
+
else:
|
|
183
|
+
overlay.hide()
|
|
184
|
+
overlay.update() # ← Call this every loop iteration!
|
|
185
|
+
time.sleep(0.1)
|
|
186
|
+
"""
|
|
187
|
+
if self.root is not None:
|
|
188
|
+
try:
|
|
189
|
+
import time
|
|
190
|
+
current_time = time.time()
|
|
191
|
+
|
|
192
|
+
# Throttle: only update every 100ms (10 FPS) to reduce CPU load
|
|
193
|
+
# This prevents excessive event processing while keeping UI responsive
|
|
194
|
+
if current_time - self._last_update_time < 0.1:
|
|
195
|
+
return # Skip this update
|
|
196
|
+
|
|
197
|
+
self._last_update_time = current_time
|
|
198
|
+
|
|
199
|
+
# Defensive check: verify window state matches _is_visible flag
|
|
200
|
+
for win in self.windows:
|
|
201
|
+
try:
|
|
202
|
+
actual_state = win.winfo_viewable()
|
|
203
|
+
if actual_state and not self._is_visible:
|
|
204
|
+
print(f"⚠️ BUG DETECTED: Window is visible but _is_visible=False! Force hiding...")
|
|
205
|
+
win.attributes('-topmost', False)
|
|
206
|
+
win.withdraw()
|
|
207
|
+
elif not actual_state and self._is_visible:
|
|
208
|
+
print(f"⚠️ BUG DETECTED: Window is hidden but _is_visible=True! Syncing flag...")
|
|
209
|
+
self._is_visible = False
|
|
210
|
+
except Exception as e:
|
|
211
|
+
pass # Ignore errors in defensive check
|
|
212
|
+
|
|
213
|
+
# Process Tkinter events
|
|
214
|
+
self.root.update()
|
|
215
|
+
except Exception as e:
|
|
216
|
+
print(f"Warning: Update failed: {e}")
|
|
155
217
|
|
|
156
218
|
def stop(self):
|
|
157
219
|
"""Stop and cleanup the overlay completely"""
|
|
158
|
-
if self.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
self.
|
|
166
|
-
|
|
167
|
-
self._command_queue = None
|
|
168
|
-
|
|
169
|
-
def _run_process(self, command_queue):
|
|
170
|
-
"""Run overlay in separate process with command queue"""
|
|
171
|
-
try:
|
|
172
|
-
# Create windows for all monitors
|
|
173
|
-
self._create_windows()
|
|
174
|
-
|
|
175
|
-
# Hide all windows initially
|
|
176
|
-
for win in self.windows:
|
|
177
|
-
win.withdraw()
|
|
178
|
-
|
|
179
|
-
# Process commands from queue
|
|
180
|
-
def check_commands():
|
|
181
|
-
try:
|
|
182
|
-
while not command_queue.empty():
|
|
183
|
-
cmd = command_queue.get_nowait()
|
|
184
|
-
if cmd == 'show':
|
|
185
|
-
for win in self.windows:
|
|
186
|
-
try:
|
|
187
|
-
win.deiconify()
|
|
188
|
-
win.lift()
|
|
189
|
-
except Exception as e:
|
|
190
|
-
print(f"Warning: Failed to show window: {e}")
|
|
191
|
-
elif cmd == 'hide':
|
|
192
|
-
for win in self.windows:
|
|
193
|
-
try:
|
|
194
|
-
win.withdraw()
|
|
195
|
-
except Exception as e:
|
|
196
|
-
print(f"Warning: Failed to hide window: {e}")
|
|
197
|
-
elif cmd == 'stop':
|
|
198
|
-
self.root.quit()
|
|
199
|
-
return
|
|
200
|
-
except Exception as e:
|
|
201
|
-
print(f"Warning: Command queue error: {e}")
|
|
202
|
-
|
|
203
|
-
# Check again in 10ms
|
|
204
|
-
self.root.after(10, check_commands)
|
|
205
|
-
|
|
206
|
-
# Start command checker
|
|
207
|
-
check_commands()
|
|
208
|
-
|
|
209
|
-
# Run mainloop
|
|
210
|
-
self.root.mainloop()
|
|
211
|
-
|
|
212
|
-
except Exception as e:
|
|
213
|
-
print(f"Overlay process error: {e}")
|
|
214
|
-
finally:
|
|
215
|
-
os._exit(0)
|
|
220
|
+
if self.root is not None:
|
|
221
|
+
try:
|
|
222
|
+
self.root.quit()
|
|
223
|
+
self.root.destroy()
|
|
224
|
+
except:
|
|
225
|
+
pass
|
|
226
|
+
self.root = None
|
|
227
|
+
self.windows = []
|
|
228
|
+
self._is_visible = False
|
|
216
229
|
|
|
217
230
|
def _get_monitors(self):
|
|
218
231
|
"""Get information about all monitors"""
|
|
@@ -274,52 +287,9 @@ class NativeBlurOverlay:
|
|
|
274
287
|
if self.apply_blur:
|
|
275
288
|
self._apply_native_blur_to_window(window)
|
|
276
289
|
|
|
277
|
-
# Bind escape key to
|
|
290
|
+
# Bind escape key to hide (only on primary window)
|
|
278
291
|
if window == self.root:
|
|
279
|
-
window.bind('<Escape>', lambda e: self.
|
|
280
|
-
window.focus_set()
|
|
281
|
-
|
|
282
|
-
def _create_window(self):
|
|
283
|
-
"""Internal method to create and configure the Tkinter window"""
|
|
284
|
-
self.root = tk.Tk()
|
|
285
|
-
|
|
286
|
-
# Remove window decorations
|
|
287
|
-
self.root.overrideredirect(True)
|
|
288
|
-
self.root.attributes('-topmost', True)
|
|
289
|
-
|
|
290
|
-
# Set background color (tint)
|
|
291
|
-
bg_color = f'#{self.color_tint[0]:02x}{self.color_tint[1]:02x}{self.color_tint[2]:02x}'
|
|
292
|
-
self.root.configure(bg=bg_color)
|
|
293
|
-
|
|
294
|
-
# Set opacity
|
|
295
|
-
self.root.attributes('-alpha', self.opacity)
|
|
296
|
-
|
|
297
|
-
# Full screen
|
|
298
|
-
screen_width = self.root.winfo_screenwidth()
|
|
299
|
-
screen_height = self.root.winfo_screenheight()
|
|
300
|
-
self.root.geometry(f"{screen_width}x{screen_height}+0+0")
|
|
301
|
-
|
|
302
|
-
# Apply native blur effect based on OS (only if mode is 'blur')
|
|
303
|
-
if self.apply_blur:
|
|
304
|
-
self._apply_native_blur()
|
|
305
|
-
|
|
306
|
-
# Bind escape key to exit
|
|
307
|
-
self.root.bind('<Escape>', lambda e: self.kill_completely())
|
|
308
|
-
self.root.focus_set()
|
|
309
|
-
|
|
310
|
-
def activate(self, duration=5):
|
|
311
|
-
"""Show native blur overlay and exit after duration"""
|
|
312
|
-
self._create_windows() # Use multi-monitor aware method
|
|
313
|
-
|
|
314
|
-
# Auto-exit timer
|
|
315
|
-
self._timer_id = self.root.after(int(duration * 1000), self.kill_completely)
|
|
316
|
-
|
|
317
|
-
# Show window
|
|
318
|
-
self.root.mainloop()
|
|
319
|
-
|
|
320
|
-
def _apply_native_blur(self):
|
|
321
|
-
"""Apply OS-native backdrop blur effect to root window (legacy method)"""
|
|
322
|
-
self._apply_native_blur_to_window(self.root)
|
|
292
|
+
window.bind('<Escape>', lambda e: self.hide())
|
|
323
293
|
|
|
324
294
|
def _apply_native_blur_to_window(self, window):
|
|
325
295
|
"""Apply OS-native backdrop blur effect to a specific window"""
|
|
@@ -331,10 +301,6 @@ class NativeBlurOverlay:
|
|
|
331
301
|
self._apply_windows_blur_to_window(window)
|
|
332
302
|
elif system == 'Linux':
|
|
333
303
|
self._apply_linux_blur_to_window(window)
|
|
334
|
-
|
|
335
|
-
def _apply_macos_blur(self):
|
|
336
|
-
"""Apply macOS NSVisualEffectView blur (legacy method)"""
|
|
337
|
-
self._apply_macos_blur_to_window(self.root)
|
|
338
304
|
|
|
339
305
|
def _apply_macos_blur_to_window(self, window):
|
|
340
306
|
"""Apply macOS NSVisualEffectView blur to a specific window"""
|
|
@@ -359,17 +325,17 @@ class NativeBlurOverlay:
|
|
|
359
325
|
from Cocoa import NSMakeRect
|
|
360
326
|
|
|
361
327
|
# Get all windows and find ours
|
|
362
|
-
for
|
|
363
|
-
if
|
|
328
|
+
for ns_window in NSApp.windows():
|
|
329
|
+
if ns_window.isVisible():
|
|
364
330
|
# Create visual effect view
|
|
365
|
-
frame =
|
|
331
|
+
frame = ns_window.contentView().frame()
|
|
366
332
|
effect_view = NSVisualEffectView.alloc().initWithFrame_(frame)
|
|
367
333
|
effect_view.setBlendingMode_(NSVisualEffectBlendingModeBehindWindow)
|
|
368
334
|
effect_view.setMaterial_(NSVisualEffectMaterialDark)
|
|
369
335
|
effect_view.setState_(1) # Active state
|
|
370
336
|
|
|
371
337
|
# Add as subview
|
|
372
|
-
|
|
338
|
+
ns_window.contentView().addSubview_positioned_relativeTo_(
|
|
373
339
|
effect_view, 0, None
|
|
374
340
|
)
|
|
375
341
|
break
|
|
@@ -380,10 +346,6 @@ class NativeBlurOverlay:
|
|
|
380
346
|
print("pyobjc not available, install with: pip install pyobjc-framework-Cocoa")
|
|
381
347
|
except Exception as e:
|
|
382
348
|
print(f"macOS blur effect failed: {e}")
|
|
383
|
-
|
|
384
|
-
def _apply_windows_blur(self):
|
|
385
|
-
"""Apply Windows Acrylic/Blur effect (legacy method)"""
|
|
386
|
-
self._apply_windows_blur_to_window(self.root)
|
|
387
349
|
|
|
388
350
|
def _apply_windows_blur_to_window(self, window):
|
|
389
351
|
"""Apply Windows Acrylic/Blur effect to a specific window"""
|
|
@@ -446,10 +408,6 @@ class NativeBlurOverlay:
|
|
|
446
408
|
# Blur effect failed, but window will still work (just without blur)
|
|
447
409
|
print(f"Note: Windows blur effect unavailable: {e}")
|
|
448
410
|
print("Overlay will work but without native blur effect")
|
|
449
|
-
|
|
450
|
-
def _apply_linux_blur(self):
|
|
451
|
-
"""Apply Linux compositor blur (X11/Wayland) (legacy method)"""
|
|
452
|
-
self._apply_linux_blur_to_window(self.root)
|
|
453
411
|
|
|
454
412
|
def _apply_linux_blur_to_window(self, window):
|
|
455
413
|
"""Apply Linux compositor blur (X11/Wayland) to a specific window"""
|
|
@@ -465,18 +423,31 @@ class NativeBlurOverlay:
|
|
|
465
423
|
except Exception as e:
|
|
466
424
|
print(f"Linux blur effect hint failed: {e}")
|
|
467
425
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
426
|
+
# Backward compatibility methods
|
|
427
|
+
def activate(self, duration=5):
|
|
428
|
+
"""
|
|
429
|
+
Show overlay for a fixed duration and then exit (blocking).
|
|
430
|
+
|
|
431
|
+
This is the legacy API for backward compatibility.
|
|
432
|
+
For new code, use start() + show()/hide() + update() instead.
|
|
433
|
+
"""
|
|
434
|
+
self.start()
|
|
435
|
+
self.show()
|
|
436
|
+
|
|
437
|
+
# Schedule hide and cleanup
|
|
438
|
+
self.root.after(int(duration * 1000), self._deactivate_and_exit)
|
|
476
439
|
|
|
477
|
-
#
|
|
478
|
-
|
|
479
|
-
|
|
440
|
+
# Run mainloop (blocking)
|
|
441
|
+
self.root.mainloop()
|
|
442
|
+
|
|
443
|
+
def _deactivate_and_exit(self):
|
|
444
|
+
"""Helper for activate() - hide and exit"""
|
|
445
|
+
self.hide()
|
|
446
|
+
self.stop()
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
# Alias for convenience
|
|
450
|
+
Overlay = NativeBlurOverlay
|
|
480
451
|
|
|
481
452
|
|
|
482
453
|
if __name__ == "__main__":
|
|
@@ -490,20 +461,19 @@ if __name__ == "__main__":
|
|
|
490
461
|
|
|
491
462
|
print(f"Testing mode='{mode}' for 3 seconds...")
|
|
492
463
|
print("Available modes: blur, black, white, custom")
|
|
493
|
-
print("Usage: python
|
|
464
|
+
print("Usage: python overlay.py [mode]")
|
|
494
465
|
print()
|
|
495
466
|
|
|
496
467
|
if mode == 'blur':
|
|
497
|
-
overlay =
|
|
468
|
+
overlay = Overlay(mode='blur', blur_strength=4)
|
|
498
469
|
elif mode == 'black':
|
|
499
|
-
overlay =
|
|
470
|
+
overlay = Overlay(mode='black')
|
|
500
471
|
elif mode == 'white':
|
|
501
|
-
overlay =
|
|
472
|
+
overlay = Overlay(mode='white')
|
|
502
473
|
elif mode == 'custom':
|
|
503
|
-
overlay =
|
|
474
|
+
overlay = Overlay(mode='custom', opacity=0.7, color_tint=(255, 0, 0)) # Red example
|
|
504
475
|
else:
|
|
505
476
|
print(f"Unknown mode: {mode}")
|
|
506
477
|
sys.exit(1)
|
|
507
478
|
|
|
508
479
|
overlay.activate(duration=3)
|
|
509
|
-
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="screenoverlay",
|
|
8
|
-
version="0.
|
|
8
|
+
version="0.6.1",
|
|
9
9
|
author="Pekay",
|
|
10
10
|
author_email="ppnicky@gmail.com",
|
|
11
11
|
description="Cross-platform screen overlay with blur, black, white, and custom modes",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|