screenoverlay 0.3.1__tar.gz → 0.4.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.3.1 → screenoverlay-0.4.1}/PKG-INFO +61 -5
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/README.md +59 -4
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/screenoverlay/__init__.py +1 -1
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/screenoverlay/overlay.py +114 -18
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/screenoverlay.egg-info/PKG-INFO +61 -5
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/screenoverlay.egg-info/requires.txt +1 -0
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/setup.py +2 -1
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/LICENSE +0 -0
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/screenoverlay.egg-info/SOURCES.txt +0 -0
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/screenoverlay.egg-info/dependency_links.txt +0 -0
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/screenoverlay.egg-info/top_level.txt +0 -0
- {screenoverlay-0.3.1 → screenoverlay-0.4.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: screenoverlay
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Cross-platform screen overlay with blur, black, white, and custom modes
|
|
5
5
|
Home-page: https://github.com/pekay-ai/screenoverlay
|
|
6
6
|
Author: Pekay
|
|
@@ -25,6 +25,7 @@ Requires-Python: >=3.7
|
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: pyobjc-framework-Cocoa; platform_system == "Darwin"
|
|
28
|
+
Requires-Dist: screeninfo
|
|
28
29
|
Provides-Extra: dev
|
|
29
30
|
Requires-Dist: pytest; extra == "dev"
|
|
30
31
|
Requires-Dist: twine; extra == "dev"
|
|
@@ -70,6 +71,7 @@ We're releasing it as **open-source (MIT)** because we believe privacy tools sho
|
|
|
70
71
|
|
|
71
72
|
- 🎭 **4 Overlay Modes** - blur, black, white, custom colors
|
|
72
73
|
- ⚡ **Ultra Fast** - <50ms startup, native OS blur effects
|
|
74
|
+
- 🖥️ **Multi-Monitor Support** - Automatically blurs ALL screens simultaneously
|
|
73
75
|
- 🔒 **No Permissions** - No screen recording access required
|
|
74
76
|
- 🌍 **Cross-Platform** - macOS, Windows, Linux
|
|
75
77
|
- 🎯 **Simple API** - One line of code to activate
|
|
@@ -384,13 +386,15 @@ Overlay(
|
|
|
384
386
|
|
|
385
387
|
- **Method:** Native OS window effects (no screen capture)
|
|
386
388
|
- **Permissions:** None required (works without screen recording access)
|
|
387
|
-
- **Memory:** Minimal footprint
|
|
389
|
+
- **Memory:** Minimal footprint (~10 MB per screen)
|
|
388
390
|
- **Process Model:** Separate process with queue-based messaging
|
|
391
|
+
- **Multi-Monitor:** Automatically detects and covers all screens
|
|
389
392
|
|
|
390
393
|
**Why so fast?** Unlike traditional screen capture approaches (400-1000ms), we use:
|
|
391
394
|
1. Native OS-level window blur effects (no image processing)
|
|
392
395
|
2. Persistent subprocess with `withdraw()`/`deiconify()` toggling
|
|
393
396
|
3. Queue-based messaging for instant communication
|
|
397
|
+
4. One window per monitor (all controlled simultaneously)
|
|
394
398
|
|
|
395
399
|
This makes `show()` and `hide()` nearly **10,000x faster** than recreating the overlay each time!
|
|
396
400
|
|
|
@@ -480,11 +484,63 @@ Contributions are welcome! Here's how you can help:
|
|
|
480
484
|
|
|
481
485
|
---
|
|
482
486
|
|
|
483
|
-
## 📄
|
|
487
|
+
## 📄 Licensing
|
|
484
488
|
|
|
485
|
-
|
|
489
|
+
ScreenOverlay uses a **dual-license model** similar to xlwings:
|
|
486
490
|
|
|
487
|
-
|
|
491
|
+
### 🆓 Non-Commercial Use (Free)
|
|
492
|
+
|
|
493
|
+
Free for individuals and non-commercial purposes:
|
|
494
|
+
|
|
495
|
+
✅ Personal projects
|
|
496
|
+
✅ Educational use
|
|
497
|
+
✅ Academic research
|
|
498
|
+
✅ Open source projects (OSI-approved licenses)
|
|
499
|
+
✅ Non-profit organizations
|
|
500
|
+
✅ Evaluation and testing
|
|
501
|
+
|
|
502
|
+
**No license key needed** - just `pip install screenoverlay` and start using it!
|
|
503
|
+
|
|
504
|
+
### 💼 Commercial Use (License Required)
|
|
505
|
+
|
|
506
|
+
A commercial license is required if you use ScreenOverlay:
|
|
507
|
+
|
|
508
|
+
💼 At a company or for commercial purposes
|
|
509
|
+
🏢 In a commercial product or service
|
|
510
|
+
💰 For client work or revenue-generating activities
|
|
511
|
+
🔧 In any business context
|
|
512
|
+
|
|
513
|
+
#### Pricing:
|
|
514
|
+
|
|
515
|
+
| License Type | Price | Use Case |
|
|
516
|
+
|--------------|-------|----------|
|
|
517
|
+
| 👨💻 **Developer** | $149/year | Single developer |
|
|
518
|
+
| 👥 **Team** | $699/year | Up to 5 developers |
|
|
519
|
+
| 🏢 **Enterprise** | Custom | Unlimited developers + priority support |
|
|
520
|
+
|
|
521
|
+
**All commercial licenses include:**
|
|
522
|
+
|
|
523
|
+
✅ Commercial use rights
|
|
524
|
+
✅ Priority email support
|
|
525
|
+
✅ Perpetual license for purchased version
|
|
526
|
+
✅ 1 year of updates
|
|
527
|
+
|
|
528
|
+
**[Purchase License](mailto:ppnicky@gmail.com?subject=ScreenOverlay%20Commercial%20License) | [Contact Sales](mailto:ppnicky@gmail.com?subject=ScreenOverlay%20Enterprise%20Inquiry)**
|
|
529
|
+
|
|
530
|
+
### ❓ Which License Do I Need?
|
|
531
|
+
|
|
532
|
+
**Simple rule:** If you're using it in a business/commercial context, you need a commercial license.
|
|
533
|
+
|
|
534
|
+
| Scenario | License Needed |
|
|
535
|
+
|----------|----------------|
|
|
536
|
+
| Personal side project (no revenue) | 🆓 Non-Commercial |
|
|
537
|
+
| Learning Python at home | 🆓 Non-Commercial |
|
|
538
|
+
| University research project | 🆓 Non-Commercial |
|
|
539
|
+
| Open source project (MIT, GPL, etc.) | 🆓 Non-Commercial |
|
|
540
|
+
| Using at your company/job | 💼 Commercial |
|
|
541
|
+
| Building a SaaS product | 💼 Commercial |
|
|
542
|
+
| Freelance client work | 💼 Commercial |
|
|
543
|
+
| Integrating into commercial software | 💼 Commercial |
|
|
488
544
|
|
|
489
545
|
---
|
|
490
546
|
|
|
@@ -27,6 +27,7 @@ We're releasing it as **open-source (MIT)** because we believe privacy tools sho
|
|
|
27
27
|
|
|
28
28
|
- 🎭 **4 Overlay Modes** - blur, black, white, custom colors
|
|
29
29
|
- ⚡ **Ultra Fast** - <50ms startup, native OS blur effects
|
|
30
|
+
- 🖥️ **Multi-Monitor Support** - Automatically blurs ALL screens simultaneously
|
|
30
31
|
- 🔒 **No Permissions** - No screen recording access required
|
|
31
32
|
- 🌍 **Cross-Platform** - macOS, Windows, Linux
|
|
32
33
|
- 🎯 **Simple API** - One line of code to activate
|
|
@@ -341,13 +342,15 @@ Overlay(
|
|
|
341
342
|
|
|
342
343
|
- **Method:** Native OS window effects (no screen capture)
|
|
343
344
|
- **Permissions:** None required (works without screen recording access)
|
|
344
|
-
- **Memory:** Minimal footprint
|
|
345
|
+
- **Memory:** Minimal footprint (~10 MB per screen)
|
|
345
346
|
- **Process Model:** Separate process with queue-based messaging
|
|
347
|
+
- **Multi-Monitor:** Automatically detects and covers all screens
|
|
346
348
|
|
|
347
349
|
**Why so fast?** Unlike traditional screen capture approaches (400-1000ms), we use:
|
|
348
350
|
1. Native OS-level window blur effects (no image processing)
|
|
349
351
|
2. Persistent subprocess with `withdraw()`/`deiconify()` toggling
|
|
350
352
|
3. Queue-based messaging for instant communication
|
|
353
|
+
4. One window per monitor (all controlled simultaneously)
|
|
351
354
|
|
|
352
355
|
This makes `show()` and `hide()` nearly **10,000x faster** than recreating the overlay each time!
|
|
353
356
|
|
|
@@ -437,11 +440,63 @@ Contributions are welcome! Here's how you can help:
|
|
|
437
440
|
|
|
438
441
|
---
|
|
439
442
|
|
|
440
|
-
## 📄
|
|
443
|
+
## 📄 Licensing
|
|
441
444
|
|
|
442
|
-
|
|
445
|
+
ScreenOverlay uses a **dual-license model** similar to xlwings:
|
|
443
446
|
|
|
444
|
-
|
|
447
|
+
### 🆓 Non-Commercial Use (Free)
|
|
448
|
+
|
|
449
|
+
Free for individuals and non-commercial purposes:
|
|
450
|
+
|
|
451
|
+
✅ Personal projects
|
|
452
|
+
✅ Educational use
|
|
453
|
+
✅ Academic research
|
|
454
|
+
✅ Open source projects (OSI-approved licenses)
|
|
455
|
+
✅ Non-profit organizations
|
|
456
|
+
✅ Evaluation and testing
|
|
457
|
+
|
|
458
|
+
**No license key needed** - just `pip install screenoverlay` and start using it!
|
|
459
|
+
|
|
460
|
+
### 💼 Commercial Use (License Required)
|
|
461
|
+
|
|
462
|
+
A commercial license is required if you use ScreenOverlay:
|
|
463
|
+
|
|
464
|
+
💼 At a company or for commercial purposes
|
|
465
|
+
🏢 In a commercial product or service
|
|
466
|
+
💰 For client work or revenue-generating activities
|
|
467
|
+
🔧 In any business context
|
|
468
|
+
|
|
469
|
+
#### Pricing:
|
|
470
|
+
|
|
471
|
+
| License Type | Price | Use Case |
|
|
472
|
+
|--------------|-------|----------|
|
|
473
|
+
| 👨💻 **Developer** | $149/year | Single developer |
|
|
474
|
+
| 👥 **Team** | $699/year | Up to 5 developers |
|
|
475
|
+
| 🏢 **Enterprise** | Custom | Unlimited developers + priority support |
|
|
476
|
+
|
|
477
|
+
**All commercial licenses include:**
|
|
478
|
+
|
|
479
|
+
✅ Commercial use rights
|
|
480
|
+
✅ Priority email support
|
|
481
|
+
✅ Perpetual license for purchased version
|
|
482
|
+
✅ 1 year of updates
|
|
483
|
+
|
|
484
|
+
**[Purchase License](mailto:ppnicky@gmail.com?subject=ScreenOverlay%20Commercial%20License) | [Contact Sales](mailto:ppnicky@gmail.com?subject=ScreenOverlay%20Enterprise%20Inquiry)**
|
|
485
|
+
|
|
486
|
+
### ❓ Which License Do I Need?
|
|
487
|
+
|
|
488
|
+
**Simple rule:** If you're using it in a business/commercial context, you need a commercial license.
|
|
489
|
+
|
|
490
|
+
| Scenario | License Needed |
|
|
491
|
+
|----------|----------------|
|
|
492
|
+
| Personal side project (no revenue) | 🆓 Non-Commercial |
|
|
493
|
+
| Learning Python at home | 🆓 Non-Commercial |
|
|
494
|
+
| University research project | 🆓 Non-Commercial |
|
|
495
|
+
| Open source project (MIT, GPL, etc.) | 🆓 Non-Commercial |
|
|
496
|
+
| Using at your company/job | 💼 Commercial |
|
|
497
|
+
| Building a SaaS product | 💼 Commercial |
|
|
498
|
+
| Freelance client work | 💼 Commercial |
|
|
499
|
+
| Integrating into commercial software | 💼 Commercial |
|
|
445
500
|
|
|
446
501
|
---
|
|
447
502
|
|
|
@@ -14,9 +14,16 @@ import time
|
|
|
14
14
|
import atexit
|
|
15
15
|
import signal
|
|
16
16
|
|
|
17
|
+
# Try to import screeninfo for multi-monitor support
|
|
18
|
+
try:
|
|
19
|
+
from screeninfo import get_monitors
|
|
20
|
+
HAS_SCREENINFO = True
|
|
21
|
+
except ImportError:
|
|
22
|
+
HAS_SCREENINFO = False
|
|
23
|
+
|
|
17
24
|
|
|
18
25
|
class NativeBlurOverlay:
|
|
19
|
-
def __init__(self, mode='blur', blur_strength=3, opacity=0.85, color_tint=(136, 136, 136)):
|
|
26
|
+
def __init__(self, mode='blur', blur_strength=3, opacity=0.85, color_tint=(136, 136, 136), all_screens=True):
|
|
20
27
|
"""
|
|
21
28
|
Initialize native overlay
|
|
22
29
|
|
|
@@ -29,9 +36,11 @@ class NativeBlurOverlay:
|
|
|
29
36
|
- blur_strength (int): How blurred/obscured (1-5, only for mode='blur')
|
|
30
37
|
- opacity (float): Window opacity (0.0 to 1.0)
|
|
31
38
|
- color_tint (tuple): RGB color tint (0-255)
|
|
39
|
+
- all_screens (bool): If True, blur all monitors. If False, only blur primary monitor (default: True)
|
|
32
40
|
"""
|
|
33
41
|
self.mode = mode.lower()
|
|
34
42
|
self.blur_strength = max(1, min(5, blur_strength))
|
|
43
|
+
self.all_screens = all_screens
|
|
35
44
|
|
|
36
45
|
# Apply mode-specific settings
|
|
37
46
|
if self.mode == 'black':
|
|
@@ -55,6 +64,7 @@ class NativeBlurOverlay:
|
|
|
55
64
|
self.apply_blur = True
|
|
56
65
|
|
|
57
66
|
self.root = None
|
|
67
|
+
self.windows = [] # List to hold multiple windows for multi-monitor
|
|
58
68
|
self._timer_id = None
|
|
59
69
|
self._process = None
|
|
60
70
|
self._command_queue = None
|
|
@@ -141,9 +151,12 @@ class NativeBlurOverlay:
|
|
|
141
151
|
def _run_process(self, command_queue):
|
|
142
152
|
"""Run overlay in separate process with command queue"""
|
|
143
153
|
try:
|
|
144
|
-
# Create
|
|
145
|
-
self.
|
|
146
|
-
|
|
154
|
+
# Create windows for all monitors
|
|
155
|
+
self._create_windows()
|
|
156
|
+
|
|
157
|
+
# Hide all windows initially
|
|
158
|
+
for win in self.windows:
|
|
159
|
+
win.withdraw()
|
|
147
160
|
|
|
148
161
|
# Process commands from queue
|
|
149
162
|
def check_commands():
|
|
@@ -151,10 +164,12 @@ class NativeBlurOverlay:
|
|
|
151
164
|
while not command_queue.empty():
|
|
152
165
|
cmd = command_queue.get_nowait()
|
|
153
166
|
if cmd == 'show':
|
|
154
|
-
self.
|
|
155
|
-
|
|
167
|
+
for win in self.windows:
|
|
168
|
+
win.deiconify()
|
|
169
|
+
win.lift()
|
|
156
170
|
elif cmd == 'hide':
|
|
157
|
-
self.
|
|
171
|
+
for win in self.windows:
|
|
172
|
+
win.withdraw()
|
|
158
173
|
elif cmd == 'stop':
|
|
159
174
|
self.root.quit()
|
|
160
175
|
return
|
|
@@ -175,6 +190,71 @@ class NativeBlurOverlay:
|
|
|
175
190
|
finally:
|
|
176
191
|
os._exit(0)
|
|
177
192
|
|
|
193
|
+
def _get_monitors(self):
|
|
194
|
+
"""Get information about all monitors"""
|
|
195
|
+
if HAS_SCREENINFO:
|
|
196
|
+
try:
|
|
197
|
+
monitors = get_monitors()
|
|
198
|
+
return [(m.x, m.y, m.width, m.height) for m in monitors]
|
|
199
|
+
except:
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
# Fallback: assume single primary monitor
|
|
203
|
+
root = tk.Tk()
|
|
204
|
+
root.withdraw()
|
|
205
|
+
width = root.winfo_screenwidth()
|
|
206
|
+
height = root.winfo_screenheight()
|
|
207
|
+
root.destroy()
|
|
208
|
+
return [(0, 0, width, height)]
|
|
209
|
+
|
|
210
|
+
def _create_windows(self):
|
|
211
|
+
"""Create overlay windows for all monitors (or just primary if all_screens=False)"""
|
|
212
|
+
monitors = self._get_monitors()
|
|
213
|
+
|
|
214
|
+
# If all_screens is False, only use primary monitor
|
|
215
|
+
if not self.all_screens:
|
|
216
|
+
monitors = monitors[:1] # Only keep first monitor
|
|
217
|
+
|
|
218
|
+
# Create primary root window
|
|
219
|
+
self.root = tk.Tk()
|
|
220
|
+
self.root.overrideredirect(True)
|
|
221
|
+
self.root.attributes('-topmost', True)
|
|
222
|
+
|
|
223
|
+
# Configure primary window for first monitor
|
|
224
|
+
if monitors:
|
|
225
|
+
x, y, width, height = monitors[0]
|
|
226
|
+
self._configure_window(self.root, x, y, width, height)
|
|
227
|
+
self.windows.append(self.root)
|
|
228
|
+
|
|
229
|
+
# Create additional windows for other monitors (only if all_screens=True)
|
|
230
|
+
for x, y, width, height in monitors[1:]:
|
|
231
|
+
win = tk.Toplevel(self.root)
|
|
232
|
+
win.overrideredirect(True)
|
|
233
|
+
win.attributes('-topmost', True)
|
|
234
|
+
self._configure_window(win, x, y, width, height)
|
|
235
|
+
self.windows.append(win)
|
|
236
|
+
|
|
237
|
+
def _configure_window(self, window, x, y, width, height):
|
|
238
|
+
"""Configure a window with overlay settings"""
|
|
239
|
+
# Set background color (tint)
|
|
240
|
+
bg_color = f'#{self.color_tint[0]:02x}{self.color_tint[1]:02x}{self.color_tint[2]:02x}'
|
|
241
|
+
window.configure(bg=bg_color)
|
|
242
|
+
|
|
243
|
+
# Set opacity
|
|
244
|
+
window.attributes('-alpha', self.opacity)
|
|
245
|
+
|
|
246
|
+
# Position and size
|
|
247
|
+
window.geometry(f"{width}x{height}+{x}+{y}")
|
|
248
|
+
|
|
249
|
+
# Apply native blur effect based on OS (only if mode is 'blur')
|
|
250
|
+
if self.apply_blur:
|
|
251
|
+
self._apply_native_blur_to_window(window)
|
|
252
|
+
|
|
253
|
+
# Bind escape key to exit (only on primary window)
|
|
254
|
+
if window == self.root:
|
|
255
|
+
window.bind('<Escape>', lambda e: self.kill_completely())
|
|
256
|
+
window.focus_set()
|
|
257
|
+
|
|
178
258
|
def _create_window(self):
|
|
179
259
|
"""Internal method to create and configure the Tkinter window"""
|
|
180
260
|
self.root = tk.Tk()
|
|
@@ -205,7 +285,7 @@ class NativeBlurOverlay:
|
|
|
205
285
|
|
|
206
286
|
def activate(self, duration=5):
|
|
207
287
|
"""Show native blur overlay and exit after duration"""
|
|
208
|
-
self.
|
|
288
|
+
self._create_windows() # Use multi-monitor aware method
|
|
209
289
|
|
|
210
290
|
# Auto-exit timer
|
|
211
291
|
self._timer_id = self.root.after(int(duration * 1000), self.kill_completely)
|
|
@@ -214,25 +294,33 @@ class NativeBlurOverlay:
|
|
|
214
294
|
self.root.mainloop()
|
|
215
295
|
|
|
216
296
|
def _apply_native_blur(self):
|
|
217
|
-
"""Apply OS-native backdrop blur effect"""
|
|
297
|
+
"""Apply OS-native backdrop blur effect to root window (legacy method)"""
|
|
298
|
+
self._apply_native_blur_to_window(self.root)
|
|
299
|
+
|
|
300
|
+
def _apply_native_blur_to_window(self, window):
|
|
301
|
+
"""Apply OS-native backdrop blur effect to a specific window"""
|
|
218
302
|
system = platform.system()
|
|
219
303
|
|
|
220
304
|
if system == 'Darwin': # macOS
|
|
221
|
-
self.
|
|
305
|
+
self._apply_macos_blur_to_window(window)
|
|
222
306
|
elif system == 'Windows':
|
|
223
|
-
self.
|
|
307
|
+
self._apply_windows_blur_to_window(window)
|
|
224
308
|
elif system == 'Linux':
|
|
225
|
-
self.
|
|
309
|
+
self._apply_linux_blur_to_window(window)
|
|
226
310
|
|
|
227
311
|
def _apply_macos_blur(self):
|
|
228
|
-
"""Apply macOS NSVisualEffectView blur"""
|
|
312
|
+
"""Apply macOS NSVisualEffectView blur (legacy method)"""
|
|
313
|
+
self._apply_macos_blur_to_window(self.root)
|
|
314
|
+
|
|
315
|
+
def _apply_macos_blur_to_window(self, window):
|
|
316
|
+
"""Apply macOS NSVisualEffectView blur to a specific window"""
|
|
229
317
|
try:
|
|
230
318
|
from Cocoa import NSView, NSVisualEffectView
|
|
231
319
|
from Cocoa import NSVisualEffectBlendingModeBehindWindow, NSVisualEffectMaterialDark
|
|
232
320
|
import objc
|
|
233
321
|
|
|
234
322
|
# Get the Tk window's NSWindow
|
|
235
|
-
window_id =
|
|
323
|
+
window_id = window.winfo_id()
|
|
236
324
|
|
|
237
325
|
# Create NSVisualEffectView
|
|
238
326
|
# Note: This requires pyobjc-framework-Cocoa
|
|
@@ -270,7 +358,11 @@ class NativeBlurOverlay:
|
|
|
270
358
|
print(f"macOS blur effect failed: {e}")
|
|
271
359
|
|
|
272
360
|
def _apply_windows_blur(self):
|
|
273
|
-
"""Apply Windows Acrylic/Blur effect"""
|
|
361
|
+
"""Apply Windows Acrylic/Blur effect (legacy method)"""
|
|
362
|
+
self._apply_windows_blur_to_window(self.root)
|
|
363
|
+
|
|
364
|
+
def _apply_windows_blur_to_window(self, window):
|
|
365
|
+
"""Apply Windows Acrylic/Blur effect to a specific window"""
|
|
274
366
|
try:
|
|
275
367
|
import ctypes
|
|
276
368
|
from ctypes import wintypes
|
|
@@ -278,10 +370,10 @@ class NativeBlurOverlay:
|
|
|
278
370
|
# Get window handle - try multiple methods
|
|
279
371
|
try:
|
|
280
372
|
# Method 1: Direct window ID
|
|
281
|
-
hwnd =
|
|
373
|
+
hwnd = window.winfo_id()
|
|
282
374
|
except:
|
|
283
375
|
# Method 2: Get parent window
|
|
284
|
-
hwnd = ctypes.windll.user32.GetParent(
|
|
376
|
+
hwnd = ctypes.windll.user32.GetParent(window.winfo_id())
|
|
285
377
|
|
|
286
378
|
if not hwnd:
|
|
287
379
|
print("Could not get window handle for blur effect")
|
|
@@ -332,7 +424,11 @@ class NativeBlurOverlay:
|
|
|
332
424
|
print("Overlay will work but without native blur effect")
|
|
333
425
|
|
|
334
426
|
def _apply_linux_blur(self):
|
|
335
|
-
"""Apply Linux compositor blur (X11/Wayland)"""
|
|
427
|
+
"""Apply Linux compositor blur (X11/Wayland) (legacy method)"""
|
|
428
|
+
self._apply_linux_blur_to_window(self.root)
|
|
429
|
+
|
|
430
|
+
def _apply_linux_blur_to_window(self, window):
|
|
431
|
+
"""Apply Linux compositor blur (X11/Wayland) to a specific window"""
|
|
336
432
|
try:
|
|
337
433
|
# Linux blur depends on compositor (KWin, Mutter, etc.)
|
|
338
434
|
# Most compositors respect window transparency and apply blur automatically
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: screenoverlay
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Cross-platform screen overlay with blur, black, white, and custom modes
|
|
5
5
|
Home-page: https://github.com/pekay-ai/screenoverlay
|
|
6
6
|
Author: Pekay
|
|
@@ -25,6 +25,7 @@ Requires-Python: >=3.7
|
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: pyobjc-framework-Cocoa; platform_system == "Darwin"
|
|
28
|
+
Requires-Dist: screeninfo
|
|
28
29
|
Provides-Extra: dev
|
|
29
30
|
Requires-Dist: pytest; extra == "dev"
|
|
30
31
|
Requires-Dist: twine; extra == "dev"
|
|
@@ -70,6 +71,7 @@ We're releasing it as **open-source (MIT)** because we believe privacy tools sho
|
|
|
70
71
|
|
|
71
72
|
- 🎭 **4 Overlay Modes** - blur, black, white, custom colors
|
|
72
73
|
- ⚡ **Ultra Fast** - <50ms startup, native OS blur effects
|
|
74
|
+
- 🖥️ **Multi-Monitor Support** - Automatically blurs ALL screens simultaneously
|
|
73
75
|
- 🔒 **No Permissions** - No screen recording access required
|
|
74
76
|
- 🌍 **Cross-Platform** - macOS, Windows, Linux
|
|
75
77
|
- 🎯 **Simple API** - One line of code to activate
|
|
@@ -384,13 +386,15 @@ Overlay(
|
|
|
384
386
|
|
|
385
387
|
- **Method:** Native OS window effects (no screen capture)
|
|
386
388
|
- **Permissions:** None required (works without screen recording access)
|
|
387
|
-
- **Memory:** Minimal footprint
|
|
389
|
+
- **Memory:** Minimal footprint (~10 MB per screen)
|
|
388
390
|
- **Process Model:** Separate process with queue-based messaging
|
|
391
|
+
- **Multi-Monitor:** Automatically detects and covers all screens
|
|
389
392
|
|
|
390
393
|
**Why so fast?** Unlike traditional screen capture approaches (400-1000ms), we use:
|
|
391
394
|
1. Native OS-level window blur effects (no image processing)
|
|
392
395
|
2. Persistent subprocess with `withdraw()`/`deiconify()` toggling
|
|
393
396
|
3. Queue-based messaging for instant communication
|
|
397
|
+
4. One window per monitor (all controlled simultaneously)
|
|
394
398
|
|
|
395
399
|
This makes `show()` and `hide()` nearly **10,000x faster** than recreating the overlay each time!
|
|
396
400
|
|
|
@@ -480,11 +484,63 @@ Contributions are welcome! Here's how you can help:
|
|
|
480
484
|
|
|
481
485
|
---
|
|
482
486
|
|
|
483
|
-
## 📄
|
|
487
|
+
## 📄 Licensing
|
|
484
488
|
|
|
485
|
-
|
|
489
|
+
ScreenOverlay uses a **dual-license model** similar to xlwings:
|
|
486
490
|
|
|
487
|
-
|
|
491
|
+
### 🆓 Non-Commercial Use (Free)
|
|
492
|
+
|
|
493
|
+
Free for individuals and non-commercial purposes:
|
|
494
|
+
|
|
495
|
+
✅ Personal projects
|
|
496
|
+
✅ Educational use
|
|
497
|
+
✅ Academic research
|
|
498
|
+
✅ Open source projects (OSI-approved licenses)
|
|
499
|
+
✅ Non-profit organizations
|
|
500
|
+
✅ Evaluation and testing
|
|
501
|
+
|
|
502
|
+
**No license key needed** - just `pip install screenoverlay` and start using it!
|
|
503
|
+
|
|
504
|
+
### 💼 Commercial Use (License Required)
|
|
505
|
+
|
|
506
|
+
A commercial license is required if you use ScreenOverlay:
|
|
507
|
+
|
|
508
|
+
💼 At a company or for commercial purposes
|
|
509
|
+
🏢 In a commercial product or service
|
|
510
|
+
💰 For client work or revenue-generating activities
|
|
511
|
+
🔧 In any business context
|
|
512
|
+
|
|
513
|
+
#### Pricing:
|
|
514
|
+
|
|
515
|
+
| License Type | Price | Use Case |
|
|
516
|
+
|--------------|-------|----------|
|
|
517
|
+
| 👨💻 **Developer** | $149/year | Single developer |
|
|
518
|
+
| 👥 **Team** | $699/year | Up to 5 developers |
|
|
519
|
+
| 🏢 **Enterprise** | Custom | Unlimited developers + priority support |
|
|
520
|
+
|
|
521
|
+
**All commercial licenses include:**
|
|
522
|
+
|
|
523
|
+
✅ Commercial use rights
|
|
524
|
+
✅ Priority email support
|
|
525
|
+
✅ Perpetual license for purchased version
|
|
526
|
+
✅ 1 year of updates
|
|
527
|
+
|
|
528
|
+
**[Purchase License](mailto:ppnicky@gmail.com?subject=ScreenOverlay%20Commercial%20License) | [Contact Sales](mailto:ppnicky@gmail.com?subject=ScreenOverlay%20Enterprise%20Inquiry)**
|
|
529
|
+
|
|
530
|
+
### ❓ Which License Do I Need?
|
|
531
|
+
|
|
532
|
+
**Simple rule:** If you're using it in a business/commercial context, you need a commercial license.
|
|
533
|
+
|
|
534
|
+
| Scenario | License Needed |
|
|
535
|
+
|----------|----------------|
|
|
536
|
+
| Personal side project (no revenue) | 🆓 Non-Commercial |
|
|
537
|
+
| Learning Python at home | 🆓 Non-Commercial |
|
|
538
|
+
| University research project | 🆓 Non-Commercial |
|
|
539
|
+
| Open source project (MIT, GPL, etc.) | 🆓 Non-Commercial |
|
|
540
|
+
| Using at your company/job | 💼 Commercial |
|
|
541
|
+
| Building a SaaS product | 💼 Commercial |
|
|
542
|
+
| Freelance client work | 💼 Commercial |
|
|
543
|
+
| Integrating into commercial software | 💼 Commercial |
|
|
488
544
|
|
|
489
545
|
---
|
|
490
546
|
|
|
@@ -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.4.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",
|
|
@@ -34,6 +34,7 @@ setup(
|
|
|
34
34
|
python_requires=">=3.7",
|
|
35
35
|
install_requires=[
|
|
36
36
|
'pyobjc-framework-Cocoa; platform_system=="Darwin"',
|
|
37
|
+
'screeninfo',
|
|
37
38
|
],
|
|
38
39
|
extras_require={
|
|
39
40
|
"dev": ["pytest", "twine", "wheel"],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|