dulus-bar 0.3.1__tar.gz → 0.3.2__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.
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/PKG-INFO +1 -1
- dulus_bar-0.3.2/dulus_bar/main.py +108 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/overlay.py +12 -1
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar.egg-info/PKG-INFO +1 -1
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/pyproject.toml +1 -1
- dulus_bar-0.3.1/dulus_bar/main.py +0 -42
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/LICENSE +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/README.md +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/__init__.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/__main__.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/agents.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/assets/dulus-bird.png +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/macos_native.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/native/__init__.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/native/base.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/native/linux.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/native/macos.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/native/windows.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar/server.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar.egg-info/SOURCES.txt +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar.egg-info/dependency_links.txt +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar.egg-info/entry_points.txt +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar.egg-info/requires.txt +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/dulus_bar.egg-info/top_level.txt +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/setup.cfg +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/tests/test_macos_native.py +0 -0
- {dulus_bar-0.3.1 → dulus_bar-0.3.2}/tests/test_server_hub.py +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Entry point for Dulus Bar.
|
|
2
|
+
|
|
3
|
+
Supports both:
|
|
4
|
+
python -m dulus_bar
|
|
5
|
+
python dulus_bar/main.py
|
|
6
|
+
|
|
7
|
+
A menu-bar / tray app must never hold a terminal hostage. When launched from a
|
|
8
|
+
console (``dulusbar`` / ``dulus-bar`` in a shell) we relaunch ourselves detached
|
|
9
|
+
with no console and return immediately, so the prompt comes straight back and
|
|
10
|
+
the app lives in the tray / status bar.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _launched_from_console() -> bool:
|
|
18
|
+
"""True when we're attached to a terminal we should escape from."""
|
|
19
|
+
if os.name == "nt":
|
|
20
|
+
try:
|
|
21
|
+
import ctypes
|
|
22
|
+
return bool(ctypes.windll.kernel32.GetConsoleWindow())
|
|
23
|
+
except Exception:
|
|
24
|
+
return False
|
|
25
|
+
try:
|
|
26
|
+
return bool(sys.stdout and sys.stdout.isatty())
|
|
27
|
+
except Exception:
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _relaunch_detached() -> bool:
|
|
32
|
+
"""Relaunch in the background with no console. Returns True on success."""
|
|
33
|
+
import subprocess
|
|
34
|
+
|
|
35
|
+
env = dict(os.environ)
|
|
36
|
+
env["DULUS_BAR_DETACHED"] = "1"
|
|
37
|
+
argv = [sys.executable, "-m", "dulus_bar"]
|
|
38
|
+
try:
|
|
39
|
+
if os.name == "nt":
|
|
40
|
+
DETACHED_PROCESS = 0x00000008
|
|
41
|
+
CREATE_NO_WINDOW = 0x08000000
|
|
42
|
+
subprocess.Popen(
|
|
43
|
+
argv,
|
|
44
|
+
env=env,
|
|
45
|
+
creationflags=DETACHED_PROCESS | CREATE_NO_WINDOW,
|
|
46
|
+
stdin=subprocess.DEVNULL,
|
|
47
|
+
stdout=subprocess.DEVNULL,
|
|
48
|
+
stderr=subprocess.DEVNULL,
|
|
49
|
+
close_fds=True,
|
|
50
|
+
)
|
|
51
|
+
else:
|
|
52
|
+
subprocess.Popen(
|
|
53
|
+
argv,
|
|
54
|
+
env=env,
|
|
55
|
+
start_new_session=True,
|
|
56
|
+
stdin=subprocess.DEVNULL,
|
|
57
|
+
stdout=subprocess.DEVNULL,
|
|
58
|
+
stderr=subprocess.DEVNULL,
|
|
59
|
+
)
|
|
60
|
+
return True
|
|
61
|
+
except Exception:
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _run() -> None:
|
|
66
|
+
try:
|
|
67
|
+
from dulus_bar.macos_native import run_native, should_use_native
|
|
68
|
+
|
|
69
|
+
if should_use_native():
|
|
70
|
+
try:
|
|
71
|
+
raise SystemExit(run_native())
|
|
72
|
+
except Exception as exc:
|
|
73
|
+
if os.environ.get("DULUS_BAR_NATIVE_REQUIRED", "0") in {"1", "true", "yes"}:
|
|
74
|
+
raise
|
|
75
|
+
print(
|
|
76
|
+
f"[dulusbar] native macOS surface unavailable ({exc}); using Qt fallback",
|
|
77
|
+
file=sys.stderr,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
from dulus_bar.overlay import run_overlay
|
|
81
|
+
|
|
82
|
+
run_overlay()
|
|
83
|
+
except SystemExit:
|
|
84
|
+
raise
|
|
85
|
+
except Exception as exc:
|
|
86
|
+
print(f"Dulus Bar crashed: {exc}", file=sys.stderr)
|
|
87
|
+
raise
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def main():
|
|
91
|
+
# Escape the terminal on first launch (unless already detached, or the user
|
|
92
|
+
# forces a foreground run with DULUS_BAR_FOREGROUND=1 for debugging).
|
|
93
|
+
if (
|
|
94
|
+
os.environ.get("DULUS_BAR_DETACHED") != "1"
|
|
95
|
+
and os.environ.get("DULUS_BAR_FOREGROUND", "0") not in {"1", "true", "yes"}
|
|
96
|
+
and _launched_from_console()
|
|
97
|
+
):
|
|
98
|
+
if _relaunch_detached():
|
|
99
|
+
return # the detached copy took over — free this terminal
|
|
100
|
+
_run()
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
if __name__ == "__main__":
|
|
104
|
+
if __package__ is None:
|
|
105
|
+
# Running directly (python dulus_bar/main.py): add project root to path.
|
|
106
|
+
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
107
|
+
sys.path.insert(0, project_root)
|
|
108
|
+
main()
|
|
@@ -423,7 +423,18 @@ class DulusBarOverlay(QMainWindow):
|
|
|
423
423
|
self.pill.setGraphicsEffect(shadow)
|
|
424
424
|
|
|
425
425
|
def _build_toast(self) -> None:
|
|
426
|
-
|
|
426
|
+
# Top-level window, NOT a child of the island. A child is clipped to the
|
|
427
|
+
# tiny island window and never shows — which is why Allow/Deny was
|
|
428
|
+
# invisible. As its own frameless, always-on-top window the permission
|
|
429
|
+
# prompt floats below the pill anywhere on screen.
|
|
430
|
+
self.toast = QWidget(None)
|
|
431
|
+
self.toast.setWindowFlags(
|
|
432
|
+
Qt.WindowType.FramelessWindowHint
|
|
433
|
+
| Qt.WindowType.WindowStaysOnTopHint
|
|
434
|
+
| Qt.WindowType.Tool
|
|
435
|
+
| Qt.WindowType.NoDropShadowWindowHint
|
|
436
|
+
)
|
|
437
|
+
self.toast.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
|
427
438
|
self.toast.setObjectName("toast")
|
|
428
439
|
self.toast.setStyleSheet(
|
|
429
440
|
f"#toast {{ background-color: {BG_HOVER}; border: 1px solid {BORDER_HOVER}; border-radius: 16px; }}"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dulus-bar"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.2"
|
|
8
8
|
description = "Dulus Bar — a cross-platform Dynamic Island for your AI agents (Windows / macOS / Linux)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"""Entry point for Dulus Bar.
|
|
2
|
-
|
|
3
|
-
Supports both:
|
|
4
|
-
python -m dulus_bar
|
|
5
|
-
python dulus_bar/main.py
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import os
|
|
9
|
-
import sys
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def main():
|
|
13
|
-
try:
|
|
14
|
-
from dulus_bar.macos_native import run_native, should_use_native
|
|
15
|
-
|
|
16
|
-
if should_use_native():
|
|
17
|
-
try:
|
|
18
|
-
raise SystemExit(run_native())
|
|
19
|
-
except Exception as exc:
|
|
20
|
-
if os.environ.get("DULUS_BAR_NATIVE_REQUIRED", "0") in {"1", "true", "yes"}:
|
|
21
|
-
raise
|
|
22
|
-
print(
|
|
23
|
-
f"[dulusbar] native macOS surface unavailable ({exc}); using Qt fallback",
|
|
24
|
-
file=sys.stderr,
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
from dulus_bar.overlay import run_overlay
|
|
28
|
-
|
|
29
|
-
run_overlay()
|
|
30
|
-
except SystemExit:
|
|
31
|
-
raise
|
|
32
|
-
except Exception as exc:
|
|
33
|
-
print(f"Dulus Bar crashed: {exc}", file=sys.stderr)
|
|
34
|
-
raise
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if __name__ == "__main__":
|
|
38
|
-
if __package__ is None:
|
|
39
|
-
# Running directly (python dulus_bar/main.py): add project root to path.
|
|
40
|
-
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
41
|
-
sys.path.insert(0, project_root)
|
|
42
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|